diff --git a/CLAUDE.md b/CLAUDE.md index 6c448e4..5c93f1a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -96,22 +96,22 @@ legacy/ # Original HTML tools for reference ## Implemented Modules (14/14 — zero placeholders) -| # | Module | Route | Version | Key Features | -| --- | ---------------------- | --------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 1 | **Dashboard** | `/` | 0.1.0 | KPI cards (6), activity feed (last 20), module grid, external tools | -| 2 | **Email Signature** | `/email-signature` | 0.1.0 | Multi-company branding, address toggle (BTG/US/SDT), live preview, zoom/copy/download | -| 3 | **Word XML Generator** | `/word-xml` | 0.1.0 | Category-based XML gen, simple/advanced mode, ZIP export | -| 4 | **Registratura** | `/registratura` | 0.2.0 | CRUD registry, dynamic doc types, bidirectional Address Book, threads, backdating, **legal deadline tracking**, recipient registration, document expiry | -| 5 | **Tag Manager** | `/tag-manager` | 0.2.0 | CRUD tags, category/scope/color, US/SDT seeds, mandatory categories, **ManicTime bidirectional sync** | -| 6 | **IT Inventory** | `/it-inventory` | 0.2.0 | Dynamic equipment types, rented status (purple pulse), **42U rack visualization**, type/status/company filters | -| 7 | **Address Book** | `/address-book` | 0.1.0 | CRUD contacts, card grid, vCard export, Registratura reverse lookup, **dynamic types (creatable)** | -| 8 | **Password Vault** | `/password-vault` | 0.3.0 | CRUD credentials, 9 categorii cu iconițe, **WiFi QR code real**, context-aware form, strength meter, company scope, **AES-256-GCM encryption** | -| 9 | **Mini Utilities** | `/mini-utilities` | 0.1.0 | Text case, char counter, percentage, area converter, U→R, artifact cleaner, MDLPA, PDF reducer, OCR | -| 10 | **Prompt Generator** | `/prompt-generator` | 0.2.0 | Template-driven prompt builder, **18 templates** (14 text + 4 image), search bar, target type filter | -| 11 | **Digital Signatures** | `/digital-signatures` | 0.1.0 | CRUD assets, drag-and-drop file upload, tag chips | -| 12 | **Word Templates** | `/word-templates` | 0.1.0 | Template library, 8 categories, version tracking, .docx placeholder auto-detection | -| 13 | **AI Chat** | `/ai-chat` | 0.2.0 | Multi-provider (OpenAI/Claude/Ollama/demo), **project linking via Tag Manager**, provider status badge | -| 14 | **Hot Desk** | `/hot-desk` | 0.1.0 | 4 desks, week-ahead calendar, room layout (window+door), reserve/cancel | +| # | Module | Route | Version | Key Features | +| --- | ---------------------- | --------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 1 | **Dashboard** | `/` | 0.1.0 | KPI cards (6), activity feed (last 20), module grid, external tools | +| 2 | **Email Signature** | `/email-signature` | 0.1.0 | Multi-company branding, address toggle (BTG/US/SDT), live preview, zoom/copy/download | +| 3 | **Word XML Generator** | `/word-xml` | 0.1.0 | Category-based XML gen, simple/advanced mode, ZIP export | +| 4 | **Registratura** | `/registratura` | 0.3.0 | CRUD registry, dynamic doc types, bidirectional Address Book, threads, backdating, **legal deadline tracking**, recipient registration, document expiry, **NAS network path attachments** (A/O/P/T drives, hostname+IP fallback) | +| 5 | **Tag Manager** | `/tag-manager` | 0.2.0 | CRUD tags, category/scope/color, US/SDT seeds, mandatory categories, **ManicTime bidirectional sync** | +| 6 | **IT Inventory** | `/it-inventory` | 0.2.0 | Dynamic equipment types, rented status (purple pulse), **42U rack visualization**, type/status/company filters | +| 7 | **Address Book** | `/address-book` | 0.1.0 | CRUD contacts, card grid, vCard export, Registratura reverse lookup, **dynamic types (creatable)** | +| 8 | **Password Vault** | `/password-vault` | 0.3.0 | CRUD credentials, 9 categorii cu iconițe, **WiFi QR code real**, context-aware form, strength meter, company scope, **AES-256-GCM encryption** | +| 9 | **Mini Utilities** | `/mini-utilities` | 0.1.0 | Text case, char counter, percentage, area converter, U→R, artifact cleaner, MDLPA, PDF reducer, OCR | +| 10 | **Prompt Generator** | `/prompt-generator` | 0.2.0 | Template-driven prompt builder, **18 templates** (14 text + 4 image), search bar, target type filter | +| 11 | **Digital Signatures** | `/digital-signatures` | 0.1.0 | CRUD assets, drag-and-drop file upload, tag chips | +| 12 | **Word Templates** | `/word-templates` | 0.1.0 | Template library, 8 categories, version tracking, .docx placeholder auto-detection | +| 13 | **AI Chat** | `/ai-chat` | 0.2.0 | Multi-provider (OpenAI/Claude/Ollama/demo), **project linking via Tag Manager**, provider status badge | +| 14 | **Hot Desk** | `/hot-desk` | 0.1.0 | 4 desks, week-ahead calendar, room layout (window+door), reserve/cancel | ### Registratura — Legal Deadline Tracking (Termene Legale) @@ -245,15 +245,16 @@ src/modules// ## Current Integrations -| Feature | Status | Notes | -| -------------------- | ---------------------- | --------------------------------------------------------------- | -| **Authentik SSO** | ✅ Active | NextAuth v4 + OIDC, group→role/company mapping | -| **PostgreSQL** | ✅ Active | Prisma ORM, `KeyValueStore` model, `/api/storage` route | -| **MinIO** | Client configured | 10.10.10.166:9002, bucket `tools`, adapter pending | -| **AI Chat API** | ✅ Multi-provider | `/api/ai-chat` — OpenAI/Claude/Ollama/demo; needs API key env | -| **Vault Encryption** | ✅ Active | AES-256-GCM server-side, `/api/vault`, ENCRYPTION_SECRET env | -| **ManicTime Sync** | ✅ Implemented | `/api/manictime` — bidirectional Tags.txt sync, needs SMB mount | -| **N8N automations** | Webhook URL configured | For notifications, backups, workflows | +| Feature | Status | Notes | +| -------------------- | ---------------------- | ------------------------------------------------------------------------------------------ | +| **Authentik SSO** | ✅ Active | NextAuth v4 + OIDC, group→role/company mapping | +| **PostgreSQL** | ✅ Active | Prisma ORM, `KeyValueStore` model, `/api/storage` route | +| **MinIO** | Client configured | 10.10.10.166:9002, bucket `tools`, adapter pending | +| **AI Chat API** | ✅ Multi-provider | `/api/ai-chat` — OpenAI/Claude/Ollama/demo; needs API key env | +| **Vault Encryption** | ✅ Active | AES-256-GCM server-side, `/api/vault`, ENCRYPTION_SECRET env | +| **ManicTime Sync** | ✅ Implemented | `/api/manictime` — bidirectional Tags.txt sync, needs SMB mount | +| **NAS Paths** | ✅ Active | `\\newamun` (10.10.10.10), drives A/O/P/T, hostname+IP fallback, `src/config/nas-paths.ts` | +| **N8N automations** | Webhook URL configured | For notifications, backups, workflows | --- diff --git a/ROADMAP.md b/ROADMAP.md index 23d72a9..c4640b4 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -32,7 +32,7 @@ | # | Module | Version | Status | Remaining Gaps | Future Enhancements | | --- | ------------------ | ------- | -------- | ---------------------------------------- | ------------------------------------------------- | -| 1 | Registratura | 0.2.0 | COMPLETE | — | Workflow automation, email integration, OCR | +| 1 | Registratura | 0.3.0 | COMPLETE | — | Workflow automation, email integration, OCR | | 2 | Email Signature | 0.1.0 | COMPLETE | US/SDT addresses may need update | AD sync, branding packs, promo banners | | 3 | Word XML | 0.1.0 | COMPLETE | — | Schema validator, visual mapper | | 4 | Digital Signatures | 0.1.0 | COMPLETE | — | Permission layers, document insertion | @@ -291,6 +291,19 @@ - ⏳ **Generare Raport/Declarație:** Necesită integrare cross-module Registratura ↔ Word Templates +### 3.03b ✅ `[STANDARD]` Registratura — NAS Network Path Attachments (2026-02-28) + +**Implementat:** + +- ✅ **NAS config** (`src/config/nas-paths.ts`): 4 drive mappings (A:\=Arhiva, O:\=Organizare, P:\=Proiecte, T:\=Transfer) +- ✅ **Hostname + IP fallback**: toate funcțiile au variante `...ByIp()` — `toUncPathByIp()`, `toFileUrlByIp()` — pentru când DNS nu rezolvă `newamun` +- ✅ **Link NAS button** în secțiunea atașamente: input inline cu validare, preview cale scurtă +- ✅ **Visual distinct**: border albastru, HardDrive icon, badge cu numele share-ului (Proiecte/Arhiva/etc.) +- ✅ **Click deschide Explorer** via `file:///` URL, buton "IP" fallback pe hover +- ✅ **Copy path** button pe hover +- ✅ **Drive letter → UNC** normalization automată (P:\ → \\newamun\Proiecte) +- ✅ **`shareLabelFor()`** helper returns human-readable share name + ### 3.04 ✅ `[ARCHITECTURE]` Autentificare & Identitate (2026-02-27) **Cerințe noi:** diff --git a/SESSION-LOG.md b/SESSION-LOG.md index ad582a7..1929448 100644 --- a/SESSION-LOG.md +++ b/SESSION-LOG.md @@ -4,6 +4,40 @@ --- +## Session — 2026-02-28c (GitHub Copilot - Claude Opus 4.6) + +### Context + +Continuation of QA improvements. NAS path enhancement: all 4 drives + DNS→IP fallback. + +### Completed + +- **NAS Network Path Attachments (enhanced):** + - 4 drive mappings: A:\=Arhiva, O:\=Organizare, P:\=Proiecte, T:\=Transfer + - `NAS_HOST` / `NAS_IP` constants used consistently across all UNC templates + - New helpers: `toUncPathByIp()`, `toFileUrlByIp()`, `shareLabelFor()` + - IP fallback: every network attachment shows an "IP" button on hover that opens via `\\10.10.10.10\...` when DNS fails + - Badge now shows share label (Proiecte/Arhiva/Organizare/Transfer) instead of generic "NAS" + - Validation hint updated to show all 4 drive letters + +- **Documentation updated:** + - CLAUDE.md: Registratura v0.3.0, NAS drives in module table, NAS row in integrations table + - ROADMAP.md: Registratura version bump, new task 3.03b with full feature list + - SESSION-LOG.md: This session entry + +### Files Changed + +- **Modified:** `src/config/nas-paths.ts` (4 drives, IP fallback helpers, shareLabelFor) +- **Modified:** `src/modules/registratura/components/registry-entry-form.tsx` (IP fallback link, share badge, validation hints) +- **Modified:** `CLAUDE.md`, `ROADMAP.md`, `SESSION-LOG.md` + +### Build + +- `npx next build` — zero errors +- Pushed to main → Portainer auto-deploy + +--- + ## Session — 2026-02-28b (GitHub Copilot - Claude Opus 4.6) ### Context diff --git a/src/config/nas-paths.ts b/src/config/nas-paths.ts index 7aeaf67..4f5b307 100644 --- a/src/config/nas-paths.ts +++ b/src/config/nas-paths.ts @@ -4,6 +4,10 @@ * The office NAS (\\newamun / 10.10.10.10) exposes several shares. * Windows maps these to drive letters. This config lets us normalise * user-pasted paths to UNC and back, and build clickable `file:///` links. + * + * Fallback strategy: hostname → IP. + * If DNS fails to resolve `newamun`, every helper has an `...ByIp()` variant + * that substitutes the hostname with the raw IP address. */ export interface NasDriveMapping { @@ -15,17 +19,18 @@ export interface NasDriveMapping { label: string; } -/** All known drive-letter → UNC mappings */ -export const NAS_DRIVE_MAPPINGS: NasDriveMapping[] = [ - { drive: "P", unc: "\\\\newamun\\Proiecte", label: "Proiecte" }, - // Add more as needed: - // { drive: "S", unc: "\\\\newamun\\Shared", label: "Shared" }, -]; - -/** NAS hostname / IP — used for display only */ +/** NAS hostname / IP */ export const NAS_HOST = "newamun"; export const NAS_IP = "10.10.10.10"; +/** All known drive-letter → UNC mappings */ +export const NAS_DRIVE_MAPPINGS: NasDriveMapping[] = [ + { drive: "A", unc: `\\\\${NAS_HOST}\\Arhiva`, label: "Arhiva" }, + { drive: "O", unc: `\\\\${NAS_HOST}\\Organizare`, label: "Organizare" }, + { drive: "P", unc: `\\\\${NAS_HOST}\\Proiecte`, label: "Proiecte" }, + { drive: "T", unc: `\\\\${NAS_HOST}\\Transfer`, label: "Transfer" }, +]; + // ── helpers ── /** @@ -34,7 +39,7 @@ export const NAS_IP = "10.10.10.10"; */ export function isNetworkPath(input: string): boolean { const trimmed = input.trim(); - // UNC path + // UNC path (hostname or IP) if (trimmed.startsWith("\\\\")) return true; // Mapped drive letter that we recognise const match = trimmed.match(/^([A-Z]):\\/i); @@ -46,7 +51,7 @@ export function isNetworkPath(input: string): boolean { } /** - * Normalise to UNC path (replace drive letter with \\newamun\Share). + * Normalise to UNC path using hostname (replace drive letter with \\newamun\Share). * If already UNC or unrecognised → returns the original trimmed. */ export function toUncPath(input: string): string { @@ -62,13 +67,36 @@ export function toUncPath(input: string): string { return trimmed; } +/** + * Swap hostname → IP in a UNC path. + * `\\newamun\Proiecte\file.pdf` → `\\10.10.10.10\Proiecte\file.pdf` + * Already-IP or unrecognised paths are returned unchanged. + */ +export function toUncPathByIp(input: string): string { + const unc = toUncPath(input); + const hostPrefix = `\\\\${NAS_HOST}\\`; + if (unc.toLowerCase().startsWith(hostPrefix.toLowerCase())) { + return `\\\\${NAS_IP}\\${unc.slice(hostPrefix.length)}`; + } + return unc; +} + /** * Build a clickable `file:///` URL from a UNC or drive-letter path. - * Windows Explorer opens this natively. + * Uses hostname by default. */ export function toFileUrl(input: string): string { const unc = toUncPath(input); - // file:///\\server\share\path → file://///server/share/path + const slashed = unc.replace(/\\/g, "/"); + return `file:///${slashed}`; +} + +/** + * Build a clickable `file:///` URL using the IP fallback. + * Use when DNS fails to resolve hostname. + */ +export function toFileUrlByIp(input: string): string { + const unc = toUncPathByIp(input); const slashed = unc.replace(/\\/g, "/"); return `file:///${slashed}`; } @@ -96,3 +124,15 @@ export function shortDisplayPath(input: string): string { const last2 = parts.slice(-2).join("\\"); return `${share}\\…\\${last2}`; } + +/** + * Return the human-readable label of the share a path belongs to. + * e.g. `P:\095\file.pdf` → `Proiecte` + */ +export function shareLabelFor(input: string): string | undefined { + const unc = toUncPath(input).toLowerCase(); + for (const m of NAS_DRIVE_MAPPINGS) { + if (unc.startsWith(m.unc.toLowerCase())) return m.label; + } + return undefined; +} diff --git a/src/modules/registratura/components/registry-entry-form.tsx b/src/modules/registratura/components/registry-entry-form.tsx index 599aa1b..7d6faef 100644 --- a/src/modules/registratura/components/registry-entry-form.tsx +++ b/src/modules/registratura/components/registry-entry-form.tsx @@ -34,8 +34,10 @@ import { isNetworkPath, toUncPath, toFileUrl, + toFileUrlByIp, pathFileName, shortDisplayPath, + shareLabelFor, } from "@/config/nas-paths"; import { Input } from "@/shared/components/ui/input"; import { Label } from "@/shared/components/ui/label"; @@ -1223,7 +1225,7 @@ export function RegistryEntryForm({
- Calea nu pare a fi pe NAS. Introdu o cale de tip P:\\... sau \\newamun\\... + Calea nu pare a fi pe NAS. Introdu o cale de tip A:\ O:\ P:\ T:\ + sau \\newamun\\...

)}
@@ -1275,7 +1278,6 @@ export function RegistryEntryForm({ className="flex-1 min-w-0 flex items-center gap-1 text-blue-700 dark:text-blue-300 hover:underline cursor-pointer" title={`Deschide în Explorer: ${att.networkPath}`} onClick={(e) => { - // file:/// links might be blocked by browser; copy path as fallback e.preventDefault(); window.open(toFileUrl(att.networkPath!), "_blank"); }} @@ -1285,11 +1287,23 @@ export function RegistryEntryForm({ {shortDisplayPath(att.networkPath)} + {/* IP fallback link — visible on hover when DNS fails */} + { + e.preventDefault(); + window.open(toFileUrlByIp(att.networkPath!), "_blank"); + }} + > + IP + - NAS + {shareLabelFor(att.networkPath) ?? "NAS"}