From 4c46e8bcdd0eec8e6bc8dc44d5382590d3292840 Mon Sep 17 00:00:00 2001 From: Marius Tarau Date: Tue, 17 Feb 2026 12:50:25 +0200 Subject: [PATCH] Initial commit: ArchiTools modular dashboard platform Complete Next.js 16 application with 13 fully implemented modules: Email Signature, Word XML Generator, Registratura, Dashboard, Tag Manager, IT Inventory, Address Book, Password Vault, Mini Utilities, Prompt Generator, Digital Signatures, Word Templates, and AI Chat. Includes core platform systems (module registry, feature flags, storage abstraction, i18n, theming, auth stub, tagging), 16 technical documentation files, Docker deployment config, and legacy HTML tool reference. Co-Authored-By: Claude Opus 4.6 --- .dockerignore | 11 + .env.example | 57 + .gitignore | 45 + Dockerfile | 33 + components.json | 23 + docker-compose.yml | 22 + docs/DATA-MODEL.md | 606 + docs/REPO-STRUCTURE.md | 563 + docs/architecture/FEATURE-FLAGS.md | 572 + docs/architecture/MODULE-SYSTEM.md | 512 + docs/architecture/SECURITY-AND-ROLES.md | 430 + docs/architecture/STORAGE-LAYER.md | 691 + docs/architecture/SYSTEM-ARCHITECTURE.md | 702 + docs/architecture/TAGGING-SYSTEM.md | 571 + docs/guides/CODING-STANDARDS.md | 684 + docs/guides/CONFIGURATION.md | 622 + docs/guides/DOCKER-DEPLOYMENT.md | 717 + docs/guides/HTML-TOOL-INTEGRATION.md | 620 + docs/guides/MODULE-DEVELOPMENT.md | 748 + docs/guides/TESTING-STRATEGY.md | 864 ++ docs/guides/UI-DESIGN-SYSTEM.md | 586 + docs/modules/PROMPT-GENERATOR.md | 1094 ++ eslint.config.mjs | 3 + .../emailsignature/emailsignature-config.html | 456 + .../manicprojects/current manic time Tags.txt | 148 + .../word-xml-generator-advanced.html | 694 + .../word-xml-generator-basic.html | 151 + .../word-xml-generator-medium.html | 330 + logo-sdt-dark.svg | 153 + logo-sdt-light.svg | 365 + logo-us-dark.svg | 22 + logo-us-light.svg | 21 + next.config.ts | 7 + package-lock.json | 11935 ++++++++++++++++ package.json | 38 + postcss.config.mjs | 7 + public/file.svg | 1 + public/globe.svg | 1 + public/next.svg | 1 + public/vercel.svg | 1 + public/window.svg | 1 + src/app/(modules)/address-book/page.tsx | 29 + src/app/(modules)/ai-chat/page.tsx | 29 + src/app/(modules)/digital-signatures/page.tsx | 29 + src/app/(modules)/email-signature/page.tsx | 29 + src/app/(modules)/it-inventory/page.tsx | 29 + src/app/(modules)/mini-utilities/page.tsx | 29 + src/app/(modules)/password-vault/page.tsx | 29 + src/app/(modules)/prompt-generator/page.tsx | 29 + src/app/(modules)/registratura/page.tsx | 29 + src/app/(modules)/tag-manager/page.tsx | 29 + src/app/(modules)/word-templates/page.tsx | 29 + src/app/(modules)/word-xml/page.tsx | 29 + src/app/favicon.ico | Bin 0 -> 25931 bytes src/app/globals.css | 126 + src/app/layout.tsx | 29 + src/app/not-found.tsx | 18 + src/app/page.tsx | 134 + src/app/providers.tsx | 31 + src/config/companies.ts | 52 + src/config/external-tools.ts | 107 + src/config/flags.ts | 119 + src/config/modules.ts | 37 + src/config/navigation.ts | 51 + src/core/auth/auth-provider.tsx | 67 + src/core/auth/index.ts | 2 + src/core/auth/types.ts | 19 + src/core/feature-flags/feature-gate.tsx | 14 + src/core/feature-flags/flag-provider.tsx | 76 + src/core/feature-flags/flag-service.ts | 74 + src/core/feature-flags/index.ts | 4 + src/core/feature-flags/types.ts | 11 + src/core/feature-flags/use-feature-flag.ts | 8 + src/core/i18n/i18n-provider.tsx | 47 + src/core/i18n/index.ts | 2 + src/core/i18n/locales/ro.ts | 109 + src/core/i18n/types.ts | 3 + src/core/module-registry/index.ts | 9 + src/core/module-registry/registry.ts | 45 + src/core/module-registry/types.ts | 32 + src/core/storage/adapters/local-storage.ts | 80 + src/core/storage/index.ts | 4 + src/core/storage/storage-provider.tsx | 33 + src/core/storage/types.ts | 10 + src/core/storage/use-storage.ts | 55 + src/core/tagging/index.ts | 3 + src/core/tagging/tag-service.ts | 61 + src/core/tagging/types.ts | 27 + src/core/tagging/use-tags.ts | 45 + src/core/theme/index.ts | 1 + src/core/theme/theme-provider.tsx | 20 + .../components/address-book-module.tsx | 168 + src/modules/address-book/config.ts | 17 + .../address-book/hooks/use-contacts.ts | 73 + src/modules/address-book/index.ts | 3 + src/modules/address-book/types.ts | 17 + .../ai-chat/components/ai-chat-module.tsx | 164 + src/modules/ai-chat/config.ts | 17 + src/modules/ai-chat/hooks/use-chat.ts | 93 + src/modules/ai-chat/index.ts | 3 + src/modules/ai-chat/types.ts | 15 + src/modules/dashboard/index.ts | 1 + src/modules/dashboard/types.ts | 9 + .../components/digital-signatures-module.tsx | 182 + src/modules/digital-signatures/config.ts | 17 + .../hooks/use-signatures.ts | 73 + src/modules/digital-signatures/index.ts | 3 + src/modules/digital-signatures/types.ts | 16 + .../components/email-signature-module.tsx | 58 + .../components/saved-signatures-panel.tsx | 78 + .../components/signature-configurator.tsx | 166 + .../components/signature-preview.tsx | 67 + src/modules/email-signature/config.ts | 17 + .../hooks/use-saved-signatures.ts | 51 + .../hooks/use-signature-config.ts | 89 + src/modules/email-signature/index.ts | 3 + .../services/company-branding.ts | 114 + .../services/signature-builder.ts | 124 + src/modules/email-signature/types.ts | 59 + .../components/it-inventory-module.tsx | 204 + src/modules/it-inventory/config.ts | 17 + .../it-inventory/hooks/use-inventory.ts | 79 + src/modules/it-inventory/index.ts | 3 + src/modules/it-inventory/types.ts | 35 + .../components/mini-utilities-module.tsx | 159 + src/modules/mini-utilities/config.ts | 17 + src/modules/mini-utilities/index.ts | 3 + src/modules/mini-utilities/types.ts | 6 + .../components/password-vault-module.tsx | 185 + src/modules/password-vault/config.ts | 17 + src/modules/password-vault/hooks/use-vault.ts | 74 + src/modules/password-vault/index.ts | 3 + src/modules/password-vault/types.ts | 23 + .../components/prompt-generator-module.tsx | 327 + src/modules/prompt-generator/config.ts | 17 + .../hooks/use-prompt-generator.ts | 110 + src/modules/prompt-generator/index.ts | 16 + .../services/builtin-templates.ts | 146 + .../services/prompt-composer.ts | 75 + src/modules/prompt-generator/types.ts | 165 + .../components/registratura-module.tsx | 128 + .../components/registry-entry-form.tsx | 118 + .../components/registry-filters.tsx | 65 + .../components/registry-table.tsx | 102 + src/modules/registratura/config.ts | 17 + .../registratura/hooks/use-registry.ts | 103 + src/modules/registratura/index.ts | 3 + .../registratura/services/registry-service.ts | 38 + src/modules/registratura/types.ts | 27 + .../components/tag-manager-module.tsx | 210 + src/modules/tag-manager/config.ts | 17 + src/modules/tag-manager/index.ts | 3 + src/modules/tag-manager/types.ts | 1 + .../components/word-templates-module.tsx | 172 + src/modules/word-templates/config.ts | 17 + .../word-templates/hooks/use-templates.ts | 75 + src/modules/word-templates/index.ts | 3 + src/modules/word-templates/types.ts | 15 + .../word-xml/components/category-manager.tsx | 143 + .../word-xml/components/word-xml-module.tsx | 57 + .../word-xml/components/xml-preview.tsx | 93 + .../word-xml/components/xml-settings.tsx | 69 + src/modules/word-xml/config.ts | 17 + src/modules/word-xml/hooks/use-xml-config.ts | 128 + src/modules/word-xml/index.ts | 3 + .../word-xml/services/category-presets.ts | 36 + .../word-xml/services/xml-generator.ts | 186 + src/modules/word-xml/types.ts | 27 + src/shared/components/layout/app-shell.tsx | 38 + src/shared/components/layout/header.tsx | 57 + src/shared/components/layout/index.ts | 3 + src/shared/components/layout/sidebar.tsx | 84 + src/shared/components/ui/badge.tsx | 48 + src/shared/components/ui/button.tsx | 64 + src/shared/components/ui/card.tsx | 92 + src/shared/components/ui/dialog.tsx | 158 + src/shared/components/ui/dropdown-menu.tsx | 257 + src/shared/components/ui/input.tsx | 21 + src/shared/components/ui/label.tsx | 24 + src/shared/components/ui/scroll-area.tsx | 58 + src/shared/components/ui/select.tsx | 190 + src/shared/components/ui/separator.tsx | 28 + src/shared/components/ui/sheet.tsx | 143 + src/shared/components/ui/switch.tsx | 35 + src/shared/components/ui/tabs.tsx | 91 + src/shared/components/ui/textarea.tsx | 18 + src/shared/components/ui/tooltip.tsx | 57 + src/shared/lib/utils.ts | 6 + tsconfig.json | 36 + 189 files changed, 33780 insertions(+) create mode 100644 .dockerignore create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 components.json create mode 100644 docker-compose.yml create mode 100644 docs/DATA-MODEL.md create mode 100644 docs/REPO-STRUCTURE.md create mode 100644 docs/architecture/FEATURE-FLAGS.md create mode 100644 docs/architecture/MODULE-SYSTEM.md create mode 100644 docs/architecture/SECURITY-AND-ROLES.md create mode 100644 docs/architecture/STORAGE-LAYER.md create mode 100644 docs/architecture/SYSTEM-ARCHITECTURE.md create mode 100644 docs/architecture/TAGGING-SYSTEM.md create mode 100644 docs/guides/CODING-STANDARDS.md create mode 100644 docs/guides/CONFIGURATION.md create mode 100644 docs/guides/DOCKER-DEPLOYMENT.md create mode 100644 docs/guides/HTML-TOOL-INTEGRATION.md create mode 100644 docs/guides/MODULE-DEVELOPMENT.md create mode 100644 docs/guides/TESTING-STRATEGY.md create mode 100644 docs/guides/UI-DESIGN-SYSTEM.md create mode 100644 docs/modules/PROMPT-GENERATOR.md create mode 100644 eslint.config.mjs create mode 100644 legacy/emailsignature/emailsignature-config.html create mode 100755 legacy/manicprojects/current manic time Tags.txt create mode 100644 legacy/wordXMLgenerator/word-xml-generator-advanced.html create mode 100644 legacy/wordXMLgenerator/word-xml-generator-basic.html create mode 100644 legacy/wordXMLgenerator/word-xml-generator-medium.html create mode 100755 logo-sdt-dark.svg create mode 100755 logo-sdt-light.svg create mode 100755 logo-us-dark.svg create mode 100755 logo-us-light.svg create mode 100644 next.config.ts create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 postcss.config.mjs create mode 100644 public/file.svg create mode 100644 public/globe.svg create mode 100644 public/next.svg create mode 100644 public/vercel.svg create mode 100644 public/window.svg create mode 100644 src/app/(modules)/address-book/page.tsx create mode 100644 src/app/(modules)/ai-chat/page.tsx create mode 100644 src/app/(modules)/digital-signatures/page.tsx create mode 100644 src/app/(modules)/email-signature/page.tsx create mode 100644 src/app/(modules)/it-inventory/page.tsx create mode 100644 src/app/(modules)/mini-utilities/page.tsx create mode 100644 src/app/(modules)/password-vault/page.tsx create mode 100644 src/app/(modules)/prompt-generator/page.tsx create mode 100644 src/app/(modules)/registratura/page.tsx create mode 100644 src/app/(modules)/tag-manager/page.tsx create mode 100644 src/app/(modules)/word-templates/page.tsx create mode 100644 src/app/(modules)/word-xml/page.tsx create mode 100644 src/app/favicon.ico create mode 100644 src/app/globals.css create mode 100644 src/app/layout.tsx create mode 100644 src/app/not-found.tsx create mode 100644 src/app/page.tsx create mode 100644 src/app/providers.tsx create mode 100644 src/config/companies.ts create mode 100644 src/config/external-tools.ts create mode 100644 src/config/flags.ts create mode 100644 src/config/modules.ts create mode 100644 src/config/navigation.ts create mode 100644 src/core/auth/auth-provider.tsx create mode 100644 src/core/auth/index.ts create mode 100644 src/core/auth/types.ts create mode 100644 src/core/feature-flags/feature-gate.tsx create mode 100644 src/core/feature-flags/flag-provider.tsx create mode 100644 src/core/feature-flags/flag-service.ts create mode 100644 src/core/feature-flags/index.ts create mode 100644 src/core/feature-flags/types.ts create mode 100644 src/core/feature-flags/use-feature-flag.ts create mode 100644 src/core/i18n/i18n-provider.tsx create mode 100644 src/core/i18n/index.ts create mode 100644 src/core/i18n/locales/ro.ts create mode 100644 src/core/i18n/types.ts create mode 100644 src/core/module-registry/index.ts create mode 100644 src/core/module-registry/registry.ts create mode 100644 src/core/module-registry/types.ts create mode 100644 src/core/storage/adapters/local-storage.ts create mode 100644 src/core/storage/index.ts create mode 100644 src/core/storage/storage-provider.tsx create mode 100644 src/core/storage/types.ts create mode 100644 src/core/storage/use-storage.ts create mode 100644 src/core/tagging/index.ts create mode 100644 src/core/tagging/tag-service.ts create mode 100644 src/core/tagging/types.ts create mode 100644 src/core/tagging/use-tags.ts create mode 100644 src/core/theme/index.ts create mode 100644 src/core/theme/theme-provider.tsx create mode 100644 src/modules/address-book/components/address-book-module.tsx create mode 100644 src/modules/address-book/config.ts create mode 100644 src/modules/address-book/hooks/use-contacts.ts create mode 100644 src/modules/address-book/index.ts create mode 100644 src/modules/address-book/types.ts create mode 100644 src/modules/ai-chat/components/ai-chat-module.tsx create mode 100644 src/modules/ai-chat/config.ts create mode 100644 src/modules/ai-chat/hooks/use-chat.ts create mode 100644 src/modules/ai-chat/index.ts create mode 100644 src/modules/ai-chat/types.ts create mode 100644 src/modules/dashboard/index.ts create mode 100644 src/modules/dashboard/types.ts create mode 100644 src/modules/digital-signatures/components/digital-signatures-module.tsx create mode 100644 src/modules/digital-signatures/config.ts create mode 100644 src/modules/digital-signatures/hooks/use-signatures.ts create mode 100644 src/modules/digital-signatures/index.ts create mode 100644 src/modules/digital-signatures/types.ts create mode 100644 src/modules/email-signature/components/email-signature-module.tsx create mode 100644 src/modules/email-signature/components/saved-signatures-panel.tsx create mode 100644 src/modules/email-signature/components/signature-configurator.tsx create mode 100644 src/modules/email-signature/components/signature-preview.tsx create mode 100644 src/modules/email-signature/config.ts create mode 100644 src/modules/email-signature/hooks/use-saved-signatures.ts create mode 100644 src/modules/email-signature/hooks/use-signature-config.ts create mode 100644 src/modules/email-signature/index.ts create mode 100644 src/modules/email-signature/services/company-branding.ts create mode 100644 src/modules/email-signature/services/signature-builder.ts create mode 100644 src/modules/email-signature/types.ts create mode 100644 src/modules/it-inventory/components/it-inventory-module.tsx create mode 100644 src/modules/it-inventory/config.ts create mode 100644 src/modules/it-inventory/hooks/use-inventory.ts create mode 100644 src/modules/it-inventory/index.ts create mode 100644 src/modules/it-inventory/types.ts create mode 100644 src/modules/mini-utilities/components/mini-utilities-module.tsx create mode 100644 src/modules/mini-utilities/config.ts create mode 100644 src/modules/mini-utilities/index.ts create mode 100644 src/modules/mini-utilities/types.ts create mode 100644 src/modules/password-vault/components/password-vault-module.tsx create mode 100644 src/modules/password-vault/config.ts create mode 100644 src/modules/password-vault/hooks/use-vault.ts create mode 100644 src/modules/password-vault/index.ts create mode 100644 src/modules/password-vault/types.ts create mode 100644 src/modules/prompt-generator/components/prompt-generator-module.tsx create mode 100644 src/modules/prompt-generator/config.ts create mode 100644 src/modules/prompt-generator/hooks/use-prompt-generator.ts create mode 100644 src/modules/prompt-generator/index.ts create mode 100644 src/modules/prompt-generator/services/builtin-templates.ts create mode 100644 src/modules/prompt-generator/services/prompt-composer.ts create mode 100644 src/modules/prompt-generator/types.ts create mode 100644 src/modules/registratura/components/registratura-module.tsx create mode 100644 src/modules/registratura/components/registry-entry-form.tsx create mode 100644 src/modules/registratura/components/registry-filters.tsx create mode 100644 src/modules/registratura/components/registry-table.tsx create mode 100644 src/modules/registratura/config.ts create mode 100644 src/modules/registratura/hooks/use-registry.ts create mode 100644 src/modules/registratura/index.ts create mode 100644 src/modules/registratura/services/registry-service.ts create mode 100644 src/modules/registratura/types.ts create mode 100644 src/modules/tag-manager/components/tag-manager-module.tsx create mode 100644 src/modules/tag-manager/config.ts create mode 100644 src/modules/tag-manager/index.ts create mode 100644 src/modules/tag-manager/types.ts create mode 100644 src/modules/word-templates/components/word-templates-module.tsx create mode 100644 src/modules/word-templates/config.ts create mode 100644 src/modules/word-templates/hooks/use-templates.ts create mode 100644 src/modules/word-templates/index.ts create mode 100644 src/modules/word-templates/types.ts create mode 100644 src/modules/word-xml/components/category-manager.tsx create mode 100644 src/modules/word-xml/components/word-xml-module.tsx create mode 100644 src/modules/word-xml/components/xml-preview.tsx create mode 100644 src/modules/word-xml/components/xml-settings.tsx create mode 100644 src/modules/word-xml/config.ts create mode 100644 src/modules/word-xml/hooks/use-xml-config.ts create mode 100644 src/modules/word-xml/index.ts create mode 100644 src/modules/word-xml/services/category-presets.ts create mode 100644 src/modules/word-xml/services/xml-generator.ts create mode 100644 src/modules/word-xml/types.ts create mode 100644 src/shared/components/layout/app-shell.tsx create mode 100644 src/shared/components/layout/header.tsx create mode 100644 src/shared/components/layout/index.ts create mode 100644 src/shared/components/layout/sidebar.tsx create mode 100644 src/shared/components/ui/badge.tsx create mode 100644 src/shared/components/ui/button.tsx create mode 100644 src/shared/components/ui/card.tsx create mode 100644 src/shared/components/ui/dialog.tsx create mode 100644 src/shared/components/ui/dropdown-menu.tsx create mode 100644 src/shared/components/ui/input.tsx create mode 100644 src/shared/components/ui/label.tsx create mode 100644 src/shared/components/ui/scroll-area.tsx create mode 100644 src/shared/components/ui/select.tsx create mode 100644 src/shared/components/ui/separator.tsx create mode 100644 src/shared/components/ui/sheet.tsx create mode 100644 src/shared/components/ui/switch.tsx create mode 100644 src/shared/components/ui/tabs.tsx create mode 100644 src/shared/components/ui/textarea.tsx create mode 100644 src/shared/components/ui/tooltip.tsx create mode 100644 src/shared/lib/utils.ts create mode 100644 tsconfig.json diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..56b59b0 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +node_modules +.next +.git +.gitignore +.env +.env.local +.env.*.local +*.md +docs/ +legacy/ +.DS_Store diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..8c1405d --- /dev/null +++ b/.env.example @@ -0,0 +1,57 @@ +# ============================================================================= +# ArchiTools - Environment Configuration +# ============================================================================= +# Copy to .env.local for local development, or .env for Docker deployment. +# Variables prefixed with NEXT_PUBLIC_ are exposed to the browser. + +# Application +NEXT_PUBLIC_APP_NAME=ArchiTools +NEXT_PUBLIC_APP_URL=http://localhost:3000 + +# Storage adapter: 'localStorage' (default) | 'api' | 'minio' +NEXT_PUBLIC_STORAGE_ADAPTER=localStorage + +# Feature flag overrides (set to 'true' or 'false') +# NEXT_PUBLIC_FLAG_MODULE_REGISTRATURA=true +# NEXT_PUBLIC_FLAG_MODULE_EMAIL_SIGNATURE=true +# NEXT_PUBLIC_FLAG_MODULE_WORD_XML=true +# NEXT_PUBLIC_FLAG_MODULE_PROMPT_GENERATOR=true +# NEXT_PUBLIC_FLAG_MODULE_DIGITAL_SIGNATURES=false +# NEXT_PUBLIC_FLAG_MODULE_PASSWORD_VAULT=false +# NEXT_PUBLIC_FLAG_MODULE_IT_INVENTORY=false +# NEXT_PUBLIC_FLAG_MODULE_ADDRESS_BOOK=false +# NEXT_PUBLIC_FLAG_MODULE_WORD_TEMPLATES=false +# NEXT_PUBLIC_FLAG_MODULE_TAG_MANAGER=true +# NEXT_PUBLIC_FLAG_MODULE_MINI_UTILITIES=false +# NEXT_PUBLIC_FLAG_MODULE_AI_CHAT=false + +# Future: API storage backend +# STORAGE_API_URL=http://api.internal/storage + +# Future: MinIO object storage +# MINIO_ENDPOINT=10.10.10.166:9003 +# MINIO_ACCESS_KEY= +# MINIO_SECRET_KEY= +# MINIO_BUCKET=architools + +# Future: Authentik SSO +# AUTHENTIK_URL=http://10.10.10.166:9100 +# AUTHENTIK_CLIENT_ID= +# AUTHENTIK_CLIENT_SECRET= + +# Future: N8N automation +# N8N_WEBHOOK_URL=http://10.10.10.166:5678/webhook + +# External tool URLs (displayed in dashboard) +NEXT_PUBLIC_GITEA_URL=http://10.10.10.166:3002 +# NEXT_PUBLIC_PORTAINER_URL= +NEXT_PUBLIC_MINIO_URL=http://10.10.10.166:9003 +NEXT_PUBLIC_N8N_URL=http://10.10.10.166:5678 +NEXT_PUBLIC_STIRLING_PDF_URL=http://10.10.10.166:8087 +NEXT_PUBLIC_IT_TOOLS_URL=http://10.10.10.166:8085 +NEXT_PUBLIC_FILEBROWSER_URL=http://10.10.10.166:8086 +NEXT_PUBLIC_UPTIME_KUMA_URL=http://10.10.10.166:3001 +NEXT_PUBLIC_NETDATA_URL=http://10.10.10.166:19999 +NEXT_PUBLIC_DOZZLE_URL=http://10.10.10.166:9999 +NEXT_PUBLIC_CROWDSEC_URL=http://10.10.10.166:8088 +NEXT_PUBLIC_AUTHENTIK_URL=http://10.10.10.166:9100 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0408bc8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,45 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem +.claude/ +context.md + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files +.env +.env.local +.env.*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5d1e9f5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,33 @@ +# Stage 1: Dependencies +FROM node:20-alpine AS deps +WORKDIR /app +COPY package.json package-lock.json ./ +RUN npm ci + +# Stage 2: Build +FROM node:20-alpine AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . +RUN npm run build + +# Stage 3: Runner +FROM node:20-alpine AS runner +WORKDIR /app + +ENV NODE_ENV=production + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 +ENV PORT=3000 +ENV HOSTNAME="0.0.0.0" + +CMD ["node", "server.js"] diff --git a/components.json b/components.json new file mode 100644 index 0000000..f5c4f9f --- /dev/null +++ b/components.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/app/globals.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "iconLibrary": "lucide", + "rtl": false, + "aliases": { + "components": "@/shared/components", + "utils": "@/shared/lib/utils", + "ui": "@/shared/components/ui", + "lib": "@/shared/lib", + "hooks": "@/shared/hooks" + }, + "registries": {} +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..8c3ad3f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,22 @@ +version: '3.8' + +services: + architools: + build: . + container_name: architools + restart: unless-stopped + ports: + - "3000:3000" + environment: + - NODE_ENV=production + - NEXT_PUBLIC_APP_URL=${APP_URL:-http://localhost:3000} + env_file: + - .env + networks: + - proxy-network + labels: + - "com.centurylinklabs.watchtower.enable=true" + +networks: + proxy-network: + external: true diff --git a/docs/DATA-MODEL.md b/docs/DATA-MODEL.md new file mode 100644 index 0000000..218c81a --- /dev/null +++ b/docs/DATA-MODEL.md @@ -0,0 +1,606 @@ +# Data Model Reference + +> Canonical type definitions and data modeling rules for ArchiTools. + +--- + +## Overview + +This document defines the shared data types, entity conventions, and relationship patterns used across all ArchiTools modules. Module-specific types extend these base types. All types live in TypeScript; the runtime representation is JSON stored through the storage abstraction layer. + +--- + +## Base Entity + +Every storable entity in the system extends `BaseEntity`: + +```typescript +// src/types/base.ts + +interface BaseEntity { + /** Unique identifier. Generated via crypto.randomUUID() or nanoid. */ + id: string; + + /** ISO 8601 timestamp. Set once at creation, never modified. */ + createdAt: string; + + /** ISO 8601 timestamp. Updated on every mutation. */ + updatedAt: string; + + /** User ID of the creator. Omitted until auth is implemented. */ + createdBy?: string; + + /** Controls who can see this entity. */ + visibility: Visibility; + + /** Cross-module tags attached to this entity. Array of tag IDs. */ + tags: string[]; + + /** Which company owns this entity. 'group' for shared/cross-company items. */ + company: CompanyId; +} +``` + +### Rules + +1. `id` is always a string. Use `crypto.randomUUID()` for generation. Never use sequential integers (they create conflicts across clients and are not merge-safe). +2. `createdAt` is set once during creation and must never change. +3. `updatedAt` is set on every save operation, including the initial creation. +4. `createdBy` is `undefined` until authentication is implemented. When auth ships, it becomes a required field on new entities. Existing entities with `undefined` are treated as created by the system. +5. `tags` stores tag IDs (not labels). Tags are resolved through the tag service. +6. `company` defaults to `'group'` for entities that are not company-specific. + +--- + +## Company Model + +```typescript +// src/types/company.ts + +type CompanyId = 'beletage' | 'urban-switch' | 'studii-de-teren' | 'group'; + +interface Company { + id: CompanyId; + name: string; // Full legal name: "Beletage SRL" + shortName: string; // Display name: "Beletage" + cui: string; // Romanian CUI (tax ID) + address?: string; // Registered address + email?: string; // Primary contact email + phone?: string; // Primary phone number +} +``` + +### Company Registry + +Defined as static configuration in `src/config/companies.ts`: + +```typescript +export const COMPANIES: Record = { + beletage: { + id: 'beletage', + name: 'Beletage SRL', + shortName: 'Beletage', + cui: '...', // populated in config + }, + 'urban-switch': { + id: 'urban-switch', + name: 'Urban Switch SRL', + shortName: 'Urban Switch', + cui: '...', + }, + 'studii-de-teren': { + id: 'studii-de-teren', + name: 'Studii de Teren SRL', + shortName: 'Studii de Teren', + cui: '...', + }, + group: { + id: 'group', + name: 'Grup Beletage', + shortName: 'Grup', + cui: '', + }, +}; +``` + +`'group'` is a virtual company representing the entire organization. Used for shared resources (templates, tags, prompts) that are not company-specific. + +--- + +## Visibility and Roles + +### Visibility + +```typescript +// src/types/visibility.ts + +type Visibility = 'all' | 'internal' | 'admin' | 'guest'; +``` + +| Value | Who can see | Use case | +|---|---|---| +| `all` | Everyone including future external/guest users | Public templates, shared contacts | +| `internal` | All authenticated internal users | Most operational data | +| `admin` | Admin users only | Passwords, sensitive config | +| `guest` | Guest users and above | Curated external-facing views | + +Until authentication is implemented, all data is treated as `internal`. The visibility field is stored but not enforced at the storage layer. Enforcement will be added at the API/middleware layer when auth ships. + +### Roles + +```typescript +// src/types/roles.ts + +type Role = 'admin' | 'user' | 'viewer' | 'guest'; +``` + +| Role | Permissions | +|---|---| +| `admin` | Full CRUD on all entities. Access to all modules. System configuration. | +| `user` | CRUD on own entities. Access to enabled modules. | +| `viewer` | Read-only access to entities matching their visibility level. | +| `guest` | Read-only access to `guest` and `all` visibility entities. Limited module access. | + +### Future Auth Integration + +When Authentik SSO is integrated: + +```typescript +interface UserProfile { + id: string; + email: string; + name: string; + role: Role; + companies: CompanyId[]; // Companies this user belongs to + modules: string[]; // Explicitly allowed modules (empty = all for role) +} +``` + +Users may belong to multiple companies. Entity filtering will combine role, visibility, and company membership. + +--- + +## Tag Model + +Tags are a cross-module resource managed by the Tag Manager module but consumed everywhere. + +```typescript +// src/types/tag.ts + +interface Tag { + /** Unique tag ID. */ + id: string; + + /** Human-readable label. Romanian. Example: "076 Casa Copernicus" */ + label: string; + + /** + * Tag category for grouping. + * Examples: 'project', 'client', 'phase', 'type', 'priority', 'domain' + */ + category: TagCategory; + + /** Display color. Hex string: "#3B82F6" */ + color: string; + + /** + * If set, this tag is only visible/usable within the specified modules. + * If undefined or empty, the tag is available globally. + */ + moduleScope?: string[]; + + /** Company this tag belongs to. 'group' for cross-company tags. */ + company: CompanyId; + + /** Whether this tag is active. Archived tags are hidden from selectors but preserved on entities. */ + archived: boolean; + + createdAt: string; + updatedAt: string; +} + +type TagCategory = + | 'project' + | 'client' + | 'phase' + | 'type' + | 'priority' + | 'domain' + | 'custom'; +``` + +### Project Reference Pattern + +Tags with category `'project'` follow the ManicTime naming convention used in the office: + +``` +"{number} {project name}" +``` + +Examples: +- `"076 Casa Copernicus"` +- `"081 PUZ Sector 3"` +- `"092 Reabilitare Scoala Nr 5"` + +The number is a sequential project identifier scoped per company. The tag label is the canonical reference; there is no separate `projectNumber` field. + +**Parsing utility:** + +```typescript +// src/lib/tags/utils.ts + +interface ParsedProjectTag { + number: string; // "076" + name: string; // "Casa Copernicus" + raw: string; // "076 Casa Copernicus" +} + +function parseProjectTag(label: string): ParsedProjectTag | null { + const match = label.match(/^(\d{3})\s+(.+)$/); + if (!match) return null; + return { number: match[1], name: match[2], raw: label }; +} +``` + +### Tag Relationships + +Tags create implicit relationships between entities across modules. For example: + +- A registratura entry tagged `"076 Casa Copernicus"` is linked to the same project as a word template with the same tag. +- Searching by tag ID across all namespaces yields every entity related to that project. + +This is the primary cross-module linking mechanism until a dedicated relational backend is introduced. + +--- + +## Module-Specific Entity Types + +Each module defines its own entity types that extend `BaseEntity`. Below is an overview of the primary entity per module. + +### Registratura + +```typescript +// src/modules/registratura/types.ts + +interface RegistryEntry extends BaseEntity { + /** Sequential registry number per company per year. "B-2025-0042" */ + registryNumber: string; + + /** Entry or exit. */ + direction: 'incoming' | 'outgoing'; + + /** Date the document was registered. ISO 8601 date (not datetime). */ + registryDate: string; + + /** Document title / description. */ + title: string; + + /** Sender (for incoming) or recipient (for outgoing). */ + correspondent: string; + + /** Number of physical pages, if applicable. */ + pageCount?: number; + + /** Reference to another registry entry (e.g., reply to incoming). */ + referenceTo?: string; + + /** Free-text notes. */ + notes?: string; + + /** Attached file references (future: MinIO object keys). */ + attachments: string[]; +} +``` + +### IT Inventory + +```typescript +// src/modules/it-inventory/types.ts + +type DeviceType = 'laptop' | 'desktop' | 'monitor' | 'printer' | 'router' | + 'switch' | 'nas' | 'phone' | 'tablet' | 'peripheral' | 'other'; + +type DeviceStatus = 'active' | 'storage' | 'repair' | 'retired' | 'disposed'; + +interface InventoryItem extends BaseEntity { + name: string; + deviceType: DeviceType; + manufacturer?: string; + model?: string; + serialNumber?: string; + purchaseDate?: string; + warrantyExpiry?: string; + assignedTo?: string; + location?: string; + status: DeviceStatus; + specs?: Record; // CPU, RAM, storage, etc. + notes?: string; +} +``` + +### Address Book + +```typescript +// src/modules/address-book/types.ts + +type ContactType = 'person' | 'company' | 'institution' | 'supplier'; + +interface AddressContact extends BaseEntity { + contactType: ContactType; + name: string; + organization?: string; + role?: string; + email?: string; + phone?: string; + address?: string; + city?: string; + county?: string; + country?: string; + cui?: string; // For companies/institutions + iban?: string; + bank?: string; + website?: string; + notes?: string; + favorite: boolean; +} +``` + +### Prompt Generator + +```typescript +// src/modules/prompt-generator/types.ts + +type PromptDomain = 'architecture' | 'legal' | 'technical' | 'gis' | + 'rendering' | 'urbanism' | 'bim' | 'procurement' | 'administrative'; + +type PromptTargetAI = 'text' | 'image' | 'code' | 'review' | 'rewrite'; + +interface PromptTemplate extends BaseEntity { + name: string; + category: string; + domain: PromptDomain; + description: string; + targetAI: PromptTargetAI; + blocks: PromptBlock[]; + variables: PromptVariable[]; + outputMode: OutputMode; + providerProfile?: string; + version: number; + parentTemplateId?: string; // For cloned/forked templates + favorite: boolean; +} +``` + +### Email Signature + +```typescript +// src/modules/email-signature/types.ts + +interface SignatureConfig extends BaseEntity { + employeeName: string; + jobTitle: string; + email: string; + phone?: string; + mobile?: string; + /** Generated HTML output. */ + generatedHtml: string; +} +``` + +### Digital Signatures + +```typescript +// src/modules/digital-signatures/types.ts + +type SignatureAssetType = 'signature' | 'stamp' | 'initials'; + +interface SignatureAsset extends BaseEntity { + name: string; + assetType: SignatureAssetType; + /** Base64-encoded PNG for localStorage. MinIO object key for API backend. */ + imageData: string; + owner?: string; + notes?: string; +} +``` + +### Password Vault + +```typescript +// src/modules/password-vault/types.ts + +interface VaultEntry extends BaseEntity { + service: string; + url?: string; + username: string; + /** Stored as plaintext in localStorage (demo-grade security). Encrypted in API backend. */ + password: string; + notes?: string; + category?: string; + lastRotated?: string; +} +``` + +> **Security note:** The localStorage adapter stores passwords in plaintext. This is acceptable only for internal demo use. The API backend must encrypt the `password` field at rest. + +### Word Templates / Word XML Generators + +```typescript +// src/modules/word-templates/types.ts + +type TemplateCategory = 'contract' | 'offer' | 'report' | 'letter' | + 'header' | 'certificate' | 'minutes' | 'other'; + +interface WordTemplate extends BaseEntity { + name: string; + category: TemplateCategory; + description?: string; + /** File reference: base64 for localStorage, MinIO key for API backend. */ + fileData: string; + fileName: string; + fileSize: number; + version: number; +} +``` + +--- + +## Naming Conventions + +### Type Names + +| Convention | Example | Used For | +|---|---|---| +| PascalCase | `RegistryEntry` | Interfaces, type aliases, classes | +| camelCase | `registryNumber` | Properties, variables, functions | +| UPPER_SNAKE_CASE | `COMPANIES` | Constants, static config objects | +| kebab-case | `'urban-switch'` | String literal union members (IDs, slugs) | + +### Entity Type Naming + +- Main entity per module: descriptive noun (`RegistryEntry`, `InventoryItem`, `AddressContact`). +- Do not prefix with module name unless ambiguity exists. +- Supporting types (enums, sub-objects): use descriptive names scoped by context (`DeviceType`, `ContactType`). +- Union string literal types: use the values themselves, not a wrapper. Prefer `type Direction = 'incoming' | 'outgoing'` over an enum. + +### File Naming + +- Type definition files: `types.ts` in the module root. +- Shared types: `src/types/{name}.ts`. +- Never put types in a barrel `index.ts` that also exports components (causes circular dependency issues with lazy loading). + +--- + +## Schema Versioning + +### Strategy + +Each module's data schema has a version number tracked in the namespace metadata: + +```typescript +// Stored at key "_meta" within each namespace +interface NamespaceMeta { + schemaVersion: number; + lastMigration: string; + itemCount: number; +} +``` + +### Migration Registration + +```typescript +// src/modules/registratura/migrations.ts + +import { defineMigrations } from '@/lib/storage/migrations'; + +export const registraturaMigrations = defineMigrations('registratura', [ + { + version: 2, + description: 'Add attachments array to registry entries', + up: (data: Record) => { + for (const [key, value] of Object.entries(data)) { + if (key === '_meta') continue; + const entry = value as Record; + if (!entry.attachments) { + entry.attachments = []; + } + } + return data; + }, + }, + { + version: 3, + description: 'Rename sender field to correspondent', + up: (data: Record) => { + for (const [key, value] of Object.entries(data)) { + if (key === '_meta') continue; + const entry = value as Record; + if ('sender' in entry) { + entry.correspondent = entry.sender; + delete entry.sender; + } + } + return data; + }, + }, +]); +``` + +### Migration Execution + +On module initialization, the storage layer: + +1. Reads `_meta.schemaVersion` for the module's namespace. +2. Compares to the latest registered migration version. +3. If behind, runs each migration sequentially (`version N` to `version N+1`). +4. Updates `_meta.schemaVersion` after each successful migration. +5. If any migration fails, the process halts and logs an error. The module should display a degraded state rather than corrupting data. + +--- + +## Entity Relationships + +ArchiTools uses a flat document model (not relational). Relationships are expressed through: + +### 1. Tags (Primary Cross-Module Link) + +Entities share project tags. Querying all namespaces for a tag ID returns every entity related to that project. + +``` +RegistryEntry.tags: ["tag-076-casa-copernicus"] +WordTemplate.tags: ["tag-076-casa-copernicus"] +PromptTemplate.tags: ["tag-076-casa-copernicus"] +``` + +### 2. Direct References + +Some entities reference others by ID within the same namespace: + +- `RegistryEntry.referenceTo` points to another registry entry ID. +- `PromptTemplate.parentTemplateId` points to the template it was cloned from. + +### 3. Company Scoping + +The `company` field on every entity enables filtering by company. A user at Beletage sees Beletage and group entities; never Urban Switch entities (unless their role grants cross-company access). + +### 4. Future: Explicit Project Entity + +When the platform matures, a `Project` entity may be introduced: + +```typescript +interface Project extends BaseEntity { + number: string; // "076" + name: string; // "Casa Copernicus" + company: CompanyId; + status: 'active' | 'completed' | 'archived'; + client?: string; // AddressContact ID + startDate?: string; + endDate?: string; +} +``` + +At that point, tags with category `'project'` would reference a `Project.id`, and the project number/name would be the single source of truth. Until then, the tag label is the canonical project identifier. + +--- + +## Shared Type Exports + +All shared types are re-exported from `src/types/index.ts`: + +```typescript +// src/types/index.ts + +export type { BaseEntity } from './base'; +export type { CompanyId, Company } from './company'; +export type { Visibility } from './visibility'; +export type { Role, UserProfile } from './roles'; +export type { Tag, TagCategory } from './tag'; +``` + +Module-specific types are not exported from this barrel. They are imported directly from the module: + +```typescript +import type { RegistryEntry } from '@/modules/registratura/types'; +``` + +This keeps the shared type surface minimal and avoids pulling module code into unrelated bundles. diff --git a/docs/REPO-STRUCTURE.md b/docs/REPO-STRUCTURE.md new file mode 100644 index 0000000..7b69bb7 --- /dev/null +++ b/docs/REPO-STRUCTURE.md @@ -0,0 +1,563 @@ +# ArchiTools — Repository Structure Reference + +This document describes every planned directory and key file in the ArchiTools repository. It serves as the canonical reference for where code belongs, what each directory contains, and what naming conventions to follow. + +--- + +## Complete Directory Tree + +``` +ArchiTools/ +├── docs/ # Internal technical documentation +│ ├── architecture/ # Architecture design documents +│ │ └── SYSTEM-ARCHITECTURE.md # Platform architecture overview +│ ├── guides/ # Developer and operational guides +│ │ ├── MODULE-DEVELOPMENT.md # How to build a new module +│ │ ├── STORAGE-LAYER.md # Storage abstraction usage +│ │ ├── FEATURE-FLAGS.md # Feature flag system guide +│ │ ├── HTML-INTEGRATION.md # Legacy HTML tool integration +│ │ ├── DOCKER-DEPLOYMENT.md # Build, deploy, and operate +│ │ ├── CODING-STANDARDS.md # Code style and conventions +│ │ └── UI-DESIGN-SYSTEM.md # Theme, components, layout rules +│ └── modules/ # Module-specific design docs +│ ├── REGISTRATURA.md # Registratura module design +│ ├── PROMPT-GENERATOR.md # Prompt Generator module design +│ └── ... # One doc per complex module +│ +├── src/ # All application source code +│ ├── app/ # Next.js App Router (routing layer) +│ │ ├── layout.tsx # Root layout +│ │ ├── page.tsx # Dashboard home page +│ │ ├── globals.css # Tailwind directives + global styles +│ │ ├── not-found.tsx # Custom 404 page +│ │ └── (modules)/ # Route group for all modules +│ │ ├── registratura/ +│ │ │ ├── page.tsx # Module list/main view +│ │ │ ├── layout.tsx # Module-level layout (optional) +│ │ │ └── [id]/ +│ │ │ └── page.tsx # Detail/edit view +│ │ ├── email-signature/ +│ │ │ └── page.tsx +│ │ ├── word-xml/ +│ │ │ └── page.tsx +│ │ ├── prompt-generator/ +│ │ │ └── page.tsx +│ │ ├── digital-signatures/ +│ │ │ └── page.tsx +│ │ ├── password-vault/ +│ │ │ └── page.tsx +│ │ ├── it-inventory/ +│ │ │ └── page.tsx +│ │ ├── address-book/ +│ │ │ └── page.tsx +│ │ ├── word-templates/ +│ │ │ └── page.tsx +│ │ ├── tag-manager/ +│ │ │ └── page.tsx +│ │ ├── mini-utilities/ +│ │ │ └── page.tsx +│ │ └── ai-chat/ +│ │ └── page.tsx +│ │ +│ ├── core/ # Platform core systems +│ │ ├── module-registry/ +│ │ │ ├── registry.ts # Module catalog and lookup functions +│ │ │ ├── types.ts # ModuleConfig, ModuleCategory types +│ │ │ └── index.ts # Public API +│ │ ├── feature-flags/ +│ │ │ ├── flag-service.ts # Flag resolution logic +│ │ │ ├── flag-provider.tsx # React context provider +│ │ │ ├── use-feature-flag.ts # Hook for flag checks +│ │ │ ├── feature-gate.tsx # Conditional render component +│ │ │ ├── types.ts # FeatureFlag, FlagScope types +│ │ │ └── index.ts # Public API +│ │ ├── storage/ +│ │ │ ├── storage-service.ts # StorageService interface definition +│ │ │ ├── storage-provider.tsx # React context provider +│ │ │ ├── use-storage.ts # Hook for storage access +│ │ │ ├── adapters/ +│ │ │ │ ├── local-storage.ts # localStorage adapter (current) +│ │ │ │ ├── minio.ts # MinIO adapter (planned) +│ │ │ │ └── database.ts # Database adapter (planned) +│ │ │ ├── types.ts # StorageAdapter, StorageOptions types +│ │ │ └── index.ts # Public API +│ │ ├── tagging/ +│ │ │ ├── tag-service.ts # Tag CRUD and query logic +│ │ │ ├── use-tags.ts # Hook for tag operations +│ │ │ ├── types.ts # Tag, TagCategory types +│ │ │ └── index.ts # Public API +│ │ ├── i18n/ +│ │ │ ├── i18n-provider.tsx # React context provider +│ │ │ ├── use-label.ts # Hook for label access +│ │ │ ├── label.tsx #