feat(registratura): add legal deadline tracking system (Termene Legale)

Full deadline tracking engine for Romanian construction permitting:
- 16 deadline types across 5 categories (Avize, Completări, Analiză, Autorizare, Publicitate)
- Working days vs calendar days with Romanian public holidays (Orthodox Easter via Meeus)
- Backward deadlines (AC extension: 45 working days BEFORE expiry)
- Chain deadlines (resolving one prompts adding the next)
- Tacit approval auto-detection (overdue + applicable type)
- Tabbed UI: Registru + Termene legale dashboard with stats/filters/table
- Inline deadline cards in entry form with add/resolve/remove
- Clock icon + count badge on registry table for entries with deadlines

Also adds CLAUDE.md with full project context for AI assistant handoff.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Marius Tarau
2026-02-18 11:27:34 +02:00
parent f0b878cf00
commit bb01268bcb
16 changed files with 1818 additions and 96 deletions
@@ -0,0 +1,220 @@
import type { DeadlineTypeDef, DeadlineCategory } from '../types';
export const DEADLINE_CATALOG: DeadlineTypeDef[] = [
// ── Avize ──
{
id: 'cerere-cu',
label: 'Cerere CU',
description: 'Termen de emitere a Certificatului de Urbanism de la data depunerii cererii.',
days: 15,
dayType: 'calendar',
startDateLabel: 'Data depunerii',
requiresCustomStartDate: false,
tacitApprovalApplicable: true,
category: 'avize',
legalReference: 'Legea 50/1991, art. 6¹',
},
{
id: 'avize-normale',
label: 'Cerere Avize normale',
description: 'Termen de emitere a avizelor de la data depunerii cererii.',
days: 15,
dayType: 'calendar',
startDateLabel: 'Data depunerii',
requiresCustomStartDate: false,
tacitApprovalApplicable: true,
category: 'avize',
},
{
id: 'aviz-cultura',
label: 'Aviz Cultură',
description: 'Termen de emitere a avizului Ministerului Culturii de la data comisiei.',
days: 30,
dayType: 'calendar',
startDateLabel: 'Data comisie',
requiresCustomStartDate: true,
startDateHint: 'Data ședinței comisiei de specialitate',
tacitApprovalApplicable: true,
category: 'avize',
},
{
id: 'aviz-mediu',
label: 'Aviz Mediu',
description: 'Termen de emitere a avizului de mediu de la finalizarea procedurilor.',
days: 15,
dayType: 'calendar',
startDateLabel: 'Data finalizare proceduri',
requiresCustomStartDate: true,
startDateHint: 'Data finalizării procedurii de evaluare de mediu',
tacitApprovalApplicable: true,
category: 'avize',
},
{
id: 'aviz-aeronautica',
label: 'Aviz Aeronautică',
description: 'Termen de emitere a avizului de la Autoritatea Aeronautică.',
days: 30,
dayType: 'calendar',
startDateLabel: 'Data depunerii',
requiresCustomStartDate: false,
tacitApprovalApplicable: true,
category: 'avize',
},
// ── Completări ──
{
id: 'completare-beneficiar',
label: 'Completare — termen beneficiar',
description: 'Termen acordat beneficiarului pentru completarea documentației.',
days: 60,
dayType: 'calendar',
startDateLabel: 'Data notificării',
requiresCustomStartDate: false,
tacitApprovalApplicable: false,
chainNextTypeId: 'completare-emitere',
chainNextActionLabel: 'Adaugă termen emitere (15 zile)',
category: 'completari',
},
{
id: 'completare-emitere',
label: 'Completare — termen emitere',
description: 'Termen de emitere după depunerea completărilor.',
days: 15,
dayType: 'calendar',
startDateLabel: 'Data depunere completări',
requiresCustomStartDate: true,
startDateHint: 'Data la care beneficiarul a depus completările',
tacitApprovalApplicable: true,
category: 'completari',
},
// ── Analiză ──
{
id: 'ctatu-analiza',
label: 'Analiză CTATU',
description: 'Termen de analiză în Comisia Tehnică de Amenajare a Teritoriului și Urbanism.',
days: 30,
dayType: 'calendar',
startDateLabel: 'Data depunerii',
requiresCustomStartDate: false,
tacitApprovalApplicable: false,
category: 'analiza',
},
{
id: 'consiliu-promovare',
label: 'Promovare Consiliu Local',
description: 'Termen de promovare în ședința Consiliului Local.',
days: 30,
dayType: 'calendar',
startDateLabel: 'Data depunerii',
requiresCustomStartDate: false,
tacitApprovalApplicable: false,
category: 'analiza',
},
{
id: 'consiliu-vot',
label: 'Vot Consiliu Local',
description: 'Termen de vot în Consiliu Local de la finalizarea dezbaterii publice.',
days: 45,
dayType: 'calendar',
startDateLabel: 'Data finalizare dezbatere',
requiresCustomStartDate: true,
startDateHint: 'Data finalizării dezbaterii publice',
tacitApprovalApplicable: false,
category: 'analiza',
},
// ── Autorizare ──
{
id: 'verificare-ac',
label: 'Verificare AC',
description: 'Termen de verificare a documentației pentru Autorizația de Construire.',
days: 5,
dayType: 'working',
startDateLabel: 'Data depunerii',
requiresCustomStartDate: false,
tacitApprovalApplicable: false,
category: 'autorizare',
},
{
id: 'prelungire-ac',
label: 'Cerere prelungire AC',
description: 'Cererea de prelungire trebuie depusă cu minim 45 zile lucrătoare ÎNAINTE de expirarea AC.',
days: 45,
dayType: 'working',
startDateLabel: 'Data expirare AC',
requiresCustomStartDate: true,
startDateHint: 'Data de expirare a Autorizației de Construire',
tacitApprovalApplicable: false,
category: 'autorizare',
isBackwardDeadline: true,
},
{
id: 'prelungire-ac-comunicare',
label: 'Comunicare decizie prelungire',
description: 'Termen de comunicare a deciziei privind prelungirea AC.',
days: 15,
dayType: 'working',
startDateLabel: 'Data depunere cerere',
requiresCustomStartDate: true,
startDateHint: 'Data depunerii cererii de prelungire',
tacitApprovalApplicable: false,
category: 'autorizare',
},
// ── Publicitate ──
{
id: 'publicitate-ac',
label: 'Publicitate AC',
description: 'Termen de publicitate a Autorizației de Construire.',
days: 30,
dayType: 'calendar',
startDateLabel: 'Data emitere AC',
requiresCustomStartDate: true,
startDateHint: 'Data emiterii Autorizației de Construire',
tacitApprovalApplicable: false,
category: 'publicitate',
},
{
id: 'plangere-prealabila',
label: 'Plângere prealabilă',
description: 'Termen de depunere a plângerii prealabile.',
days: 30,
dayType: 'calendar',
startDateLabel: 'Data ultimă publicitate',
requiresCustomStartDate: true,
startDateHint: 'Data ultimei publicități / aduceri la cunoștință',
tacitApprovalApplicable: false,
chainNextTypeId: 'contestare-instanta',
chainNextActionLabel: 'Adaugă termen contestare instanță (60 zile)',
category: 'publicitate',
},
{
id: 'contestare-instanta',
label: 'Contestare în instanță',
description: 'Termen de contestare în instanța de contencios administrativ.',
days: 60,
dayType: 'calendar',
startDateLabel: 'Data răspuns plângere',
requiresCustomStartDate: true,
startDateHint: 'Data primirii răspunsului la plângerea prealabilă',
tacitApprovalApplicable: false,
category: 'publicitate',
},
];
export const CATEGORY_LABELS: Record<DeadlineCategory, string> = {
avize: 'Avize',
completari: 'Completări',
analiza: 'Analiză',
autorizare: 'Autorizare',
publicitate: 'Publicitate',
};
export function getDeadlineType(typeId: string): DeadlineTypeDef | undefined {
return DEADLINE_CATALOG.find((d) => d.id === typeId);
}
export function getDeadlinesByCategory(category: DeadlineCategory): DeadlineTypeDef[] {
return DEADLINE_CATALOG.filter((d) => d.category === category);
}