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,97 @@
export class DateUtil {
static getCurrentTimestamp(): Date {
return new Date();
}
static getTimestampInSeconds(): number {
return Math.floor(Date.now() / 1000);
}
static addDays(date: Date, days: number): Date {
const result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}
static addHours(date: Date, hours: number): Date {
const result = new Date(date);
result.setHours(result.getHours() + hours);
return result;
}
static addMinutes(date: Date, minutes: number): Date {
const result = new Date(date);
result.setMinutes(result.getMinutes() + minutes);
return result;
}
static addSeconds(date: Date, seconds: number): Date {
const result = new Date(date);
result.setSeconds(result.getSeconds() + seconds);
return result;
}
static isExpired(date: Date): boolean {
return date < this.getCurrentTimestamp();
}
static getDifferenceInSeconds(date1: Date, date2: Date): number {
return Math.floor((date1.getTime() - date2.getTime()) / 1000);
}
static getDifferenceInMinutes(date1: Date, date2: Date): number {
return Math.floor(this.getDifferenceInSeconds(date1, date2) / 60);
}
static getDifferenceInHours(date1: Date, date2: Date): number {
return Math.floor(this.getDifferenceInMinutes(date1, date2) / 60);
}
static getDifferenceInDays(date1: Date, date2: Date): number {
return Math.floor(this.getDifferenceInHours(date1, date2) / 24);
}
static startOfDay(date: Date = new Date()): Date {
const result = new Date(date);
result.setHours(0, 0, 0, 0);
return result;
}
static endOfDay(date: Date = new Date()): Date {
const result = new Date(date);
result.setHours(23, 59, 59, 999);
return result;
}
static startOfMonth(date: Date = new Date()): Date {
const result = new Date(date);
result.setDate(1);
result.setHours(0, 0, 0, 0);
return result;
}
static endOfMonth(date: Date = new Date()): Date {
const result = new Date(date.getFullYear(), date.getMonth() + 1, 0);
result.setHours(23, 59, 59, 999);
return result;
}
static formatISO(date: Date): string {
return date.toISOString();
}
static formatDate(date: Date, format: string = 'DD/MM/YYYY'): string {
const day = String(date.getDate()).padStart(2, '0');
const month = String(date.getMonth() + 1).padStart(2, '0');
const year = date.getFullYear();
return format
.replace('DD', day)
.replace('MM', month)
.replace('YYYY', year.toString());
}
static parseISO(dateString: string): Date {
return new Date(dateString);
}
}