feat: Goa GEL Blockchain e-Licensing Platform - Full Stack Implementation

Complete implementation of the Goa Government e-Licensing platform with:

Backend:
- NestJS API with JWT authentication
- PostgreSQL database with Knex ORM
- Redis caching and session management
- MinIO document storage
- Hyperledger Besu blockchain integration
- Multi-department workflow system
- Comprehensive API tests (266/282 passing)

Frontend:
- Angular 21 with standalone components
- Angular Material + TailwindCSS UI
- Visual workflow builder
- Document upload with progress tracking
- Blockchain explorer integration
- Role-based dashboards (Admin, Department, Citizen)
- E2E tests with Playwright (37 tests)

Infrastructure:
- Docker Compose orchestration
- Blockscout blockchain explorer
- Development and production configurations
This commit is contained in:
Mahi
2026-02-07 10:23:29 -04:00
commit 80566bf0a2
441 changed files with 102418 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatTableModule } from '@angular/material/table';
import { MatChipsModule } from '@angular/material/chips';
import { MatCardModule } from '@angular/material/card';
import { ApiService } from '../../../core/services/api.service';
@Component({
selector: 'app-user-list',
standalone: true,
imports: [CommonModule, MatTableModule, MatChipsModule, MatCardModule],
template: `
<mat-card>
<mat-card-header>
<mat-card-title>All Users</mat-card-title>
</mat-card-header>
<mat-card-content>
<table mat-table [dataSource]="users" class="full-width">
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>Name</th>
<td mat-cell *matCellDef="let user">{{ user.name }}</td>
</ng-container>
<ng-container matColumnDef="email">
<th mat-header-cell *matHeaderCellDef>Email</th>
<td mat-cell *matCellDef="let user">{{ user.email }}</td>
</ng-container>
<ng-container matColumnDef="role">
<th mat-header-cell *matHeaderCellDef>Role</th>
<td mat-cell *matCellDef="let user">
<mat-chip>{{ user.role }}</mat-chip>
</td>
</ng-container>
<ng-container matColumnDef="wallet">
<th mat-header-cell *matHeaderCellDef>Wallet</th>
<td mat-cell *matCellDef="let user"><code class="wallet-addr">{{ user.walletAddress }}</code></td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
</mat-card-content>
</mat-card>
`,
styles: [`
.full-width { width: 100%; }
.wallet-addr { font-size: 0.75rem; }
`]
})
export class UserListComponent implements OnInit {
users: any[] = [];
displayedColumns = ['name', 'email', 'role', 'wallet'];
constructor(private api: ApiService) {}
async ngOnInit() {
try {
this.users = await this.api.get<any[]>('/admin/users').toPromise() || [];
} catch (error) {
console.error('Failed to load users', error);
}
}
}