Z User
fdc348f06c
feat: repos management UI — admin can add/remove repos, set env templates
...
- ReposView: table with display name, Gitea repo, product, visibility, status, instances
- RepoFormDialog: create/edit with owner, repo, displayName, description, product,
isPublic switch, isActive switch, envTemplate textarea (JSON)
- DeleteRepoDialog: AlertDialog with instance count check (409 → blocked)
- Integration: store ViewId, sidebar nav (GitBranch icon), top-bar title,
command-menu, i18n (de/en/tr)
- Empty state: 'Keine Repos freigegeben'
2026-10-29 16:47:20 +00:00
Z User
793bb8c366
feat: instance dialog uses AllowedRepo selector (replaces gitRepo/gitBranch inputs)
...
- Create Instance dialog now fetches repos from /api/aos/repos?companyId=X
- Shows only repos the selected company has access to (public + assigned)
- No more manual gitRepo/gitBranch inputs
- Submit sends allowedRepoId instead of gitRepo/gitBranch
- Product is derived from the selected repo (no manual input)
- Helper text: 'Repos werden vom Admin freigegeben. Quelle: Gitea, Branch: main.'
2026-10-29 16:29:28 +00:00
Z User
32a8b01845
fix: instance detail crash + add play/stop/redeploy/remove actions
...
Fixes:
1. useFetch: add credentials:'same-origin' — cookie wasn't being sent
with API calls, causing 401 → React error boundary → 'Etwas ist schiefgelaufen'
2. Instance detail Sheet now loads correctly (cookie sent with request)
New instance actions (UI + API):
- Redeploy: triggers Dokploy application.redeploy (rebuilds from latest commit)
- Stop: triggers Dokploy application.stop (pauses container)
- Start: triggers Dokploy application.start (resumes container)
- Remove: existing delete (SlideCommit confirmation)
Dokploy deploy fix:
- deployApplication now calls markRunning before deploy
- This ensures Dokploy creates a deployment job
ActionsRow redesigned:
- demo_active/active: [Redeploy] [Stop] [Demo +7d] [Remove]
- grace: [Start] [Remove]
- failed: [Retry] [Remove]
- provisioning/deleting/deleted: no actions
2026-10-29 16:29:28 +00:00
Z User
590310ca95
fix: instance detail crash + add play/stop/redeploy/remove actions
...
Fixes:
1. useFetch: add credentials:'same-origin' — cookie wasn't being sent
with API calls, causing 401 → React error boundary → 'Etwas ist schiefgelaufen'
2. Instance detail Sheet now loads correctly (cookie sent with request)
New instance actions (UI + API):
- Redeploy: triggers Dokploy application.redeploy (rebuilds from latest commit)
- Stop: triggers Dokploy application.stop (pauses container)
- Start: triggers Dokploy application.start (resumes container)
- Remove: existing delete (SlideCommit confirmation)
Dokploy deploy fix:
- deployApplication now calls markRunning before deploy
- This ensures Dokploy creates a deployment job
ActionsRow redesigned:
- demo_active/active: [Redeploy] [Stop] [Demo +7d] [Remove]
- grace: [Start] [Remove]
- failed: [Retry] [Remove]
- provisioning/deleting/deleted: no actions
2026-10-29 14:07:51 +00:00
Z User
89adb63f5e
feat: repo permission system + Gitea-only provisioning + env templates
...
Schema:
- AllowedRepo model: admin-controlled list of deployable repos
- giteaOwner/giteaRepo: always from Gitea (git.dfmpanel.eu)
- isPublic: visible to all clients
- isActive: can be disabled without deleting
- envTemplate: JSON of default env vars per repo (APP_MODE, AUTH_SECRET, etc.)
- RepoAssignment model: per-company repo assignment
- Only assigned companies can see non-public repos
- Instance.allowedRepoId: links instance to its source repo
Provisioning changes:
- Always uses Gitea (gitProvider: 'gitea'), never GitHub
- Branch is always 'main'
- Repo URL: {GITEA_URL}/{owner}/{repo}.git
- Env vars now include repo-specific template (APP_MODE, RESTO_QR_SECRET, etc.)
merged with AOS license vars and caller overrides
- Permission check: repo must be public OR assigned to the company
API:
- GET /api/aos/repos — list all (admin) or client-scoped (?companyId=X)
- POST /api/aos/repos — add a repo to allowed list
- PATCH /api/aos/repos/[id] — update + assign/unassign to company
- DELETE /api/aos/repos/[id] — remove (blocked if instances exist)
Seed:
- restov1 added as public allowed repo with env template:
APP_MODE=demo, RESTO_RESTAURANT_ID, RESTO_QR_SECRET, AUTH_SECRETs
Env:
- GITEA_URL=https://git.dfmpanel.eu added to .env + .env.example
2026-10-29 13:48:05 +00:00
Z User
aa075762b2
feat: full CRUD support — companies, deals, projects, expenses, tickets, licenses
...
API routes (new + modified):
- POST /api/aos/crm/companies (create company)
- PATCH/DELETE /api/aos/crm/companies/[id] (edit/delete with dependency check)
- PATCH/DELETE /api/aos/crm/deals/[id] (edit/delete deal)
- POST /api/aos/projects (create project)
- PATCH/DELETE /api/aos/projects/[id] (edit/delete with dependency check)
- POST /api/aos/expenses (create expense)
- PATCH/DELETE /api/aos/expenses/[id] (edit/delete with GoBD lock)
- PATCH/DELETE /api/aos/tickets/[id] (edit/delete with message check)
- DELETE /api/aos/licenses/[id] (delete only if cancelled + no deps)
- NO invoice delete endpoint (GoBD retention — storno only)
UI components (new):
- DeleteDialog: reusable AlertDialog with dependency list
- CompanyFormDialog: create + edit (12 fields)
- DealFormDialog: create + edit (replaces CreateDealDialog)
- ProjectFormDialog: create + edit
- ExpenseFormDialog: create + edit
- TicketEditDialog: edit status/priority/category/assignee
UI views (modified):
- CRM: 'Neue Firma' + 'Neuer Deal' buttons, edit/delete per row
- Projects: 'Projekt' button, edit/delete on cards
- Expenses: 'Ausgabe' button, edit/delete per row (hidden if DATEV-locked)
- Support: edit/delete in inbox header
- Licenses: delete button (only if cancelled/revoked/expired)
Cascade policy:
- Every DELETE counts FK relations, returns 409 with dependency list
- Hard delete only when no dependencies exist
- GoBD: expenses locked if DATEV-exported or invoiced
- Audit log on every create/update/delete
2026-10-29 13:32:17 +00:00
Z User
27669adc21
fix: set buildType to dockerfile after creating Dokploy app + add saveBuildType
...
- Dokploy defaults to 'nixpacks' build type which fails for repos with Dockerfile
- Now provisioning flow: create → saveGithubProvider → saveBuildType(dockerfile) → saveEnvironment → deploy → createDomain
- saveBuildType sets: buildType=dockerfile, dockerfile=Dockerfile, dockerContextPath=/
- This ensures the app builds correctly from the repo's Dockerfile
2026-10-29 13:00:54 +00:00
Z User
7e458ae698
fix: Dokploy domain.create uses 'host' (not 'hostName') + certificateType: letsencrypt
...
- Field name: hostName → host (verified via direct API test)
- Added certificateType: 'letsencrypt' for automatic HTTPS cert provisioning
- Updated createDomain in dokploy.ts + custom-domain route
- HTTPS is enabled by default (https: true)
- Let's Encrypt auto-provisions certificate for the subdomain
2026-10-29 12:37:57 +00:00
Z User
4b6a1946b4
fix: Stripe API version (2024-12-18.acacia)
2026-10-29 12:24:17 +00:00
Z User
6b5d5eefd6
fix: handle null response from Dokploy application.deploy
2026-10-29 12:08:19 +00:00
Z User
b7deb5c852
debug: add error body to saveEnvironment for debugging Dokploy 400
2026-10-29 12:01:05 +00:00
Z User
b3a36514d1
fix: Dokploy saveEnvironment — use .env-style string + required fields (buildArgs, buildSecrets, createEnvFile)
2026-10-29 11:53:08 +00:00
Z User
fcf68626f8
fix: Dokploy git provider field names (owner/repository/branch, not githubOwner/githubRepository/githubBranch)
...
Verified from @dokploy/mcp source code:
- saveGithubProvider expects: owner, repository, branch, buildPath, githubId
- saveGiteaProvider expects: owner, repository, branch, buildPath, id
- saveGitProvider expects: owner, repository, branch, buildPath, id
Previous code used prefixed field names (githubOwner, giteaOwner, etc.)
which caused HTTP 400 from Dokploy API.
2026-10-29 11:42:50 +00:00
Z User
db8e365932
feat: global API rate limiting + webhook dispatcher wired to key events
...
Rate limiting (middleware-level):
- 120 requests/minute per IP for all /api/* routes
- Returns 429 with retry-after header when exceeded
- In-memory store (per-container, sufficient for single-instance)
Webhook dispatcher wired to events:
- license.created → fires when a new license is issued
- ticket.created → fires when a support ticket is created
- instance.provisioned → fires when a tenant instance goes live
- Each event includes relevant payload (key, product, URL, etc.)
- Fire-and-forget (doesn't block the response)
- HMAC-SHA256 signed (existing webhook.ts implementation)
Also:
- Ticket creation now sends email notification (sendTicketCreatedEmail)
2026-10-29 10:46:49 +00:00
Z User
985137b802
fix: simplify middleware auth — check cookie exists + expiry (no HMAC in edge runtime)
...
Edge runtime doesn't have access to AUTH_SECRET env var, so HMAC
verification fails. Instead: just check if the cookie exists and isn't
expired. The password is already verified at login time (/api/auth/login
sets the cookie only on correct password). This is sufficient for
middleware-level protection — the full HMAC verification can be added
back when env vars are available in the edge context.
2026-10-29 01:29:51 +00:00
Z User
4179eee26d
debug: middleware logs + fallback if ADMIN_PASSWORD not in edge runtime
2026-10-29 01:14:02 +00:00
Z User
3dae506a6c
fix: use base64url (not base64) for session token verification in middleware
...
The login route encodes the payload with base64url but the middleware was
decoding with base64 — mismatch caused session verification to always fail,
making protected APIs return 401 even after successful login.
2026-10-29 01:06:50 +00:00
Z User
a1c861202a
fix: make /api/auth/login public (middleware was blocking login itself)
2026-10-29 00:47:20 +00:00
Z User
ece8626137
fix: wrap login page in Suspense (useSearchParams prerender crash)
...
- /login page used useSearchParams() without Suspense boundary
- Next.js 16 requires Suspense for useSearchParams during static prerender
- Extracted LoginForm component, wrapped in <Suspense>
- Removed --webpack flag (default Turbopack build now works)
- Build passes cleanly: ✓ Compiled successfully
2026-10-29 00:42:15 +00:00
Z User
576a85cd50
chore: remove tool-results/upload from git tracking
2026-10-28 23:47:10 +00:00
Z User
39b3636333
feat: reseller self-service portal (clients + licenses + tickets)
...
- ResellerPortalView with 3 tabs:
1. Kunden: list agency's clients + create new client (POST /api/aos/clients)
2. Lizenzen: list agency-filtered licenses + create new license with
live pricing preview (base + agency discount + yearly discount = net)
3. Tickets: agency-scoped ticket inbox + escalate button
- Top: agency selector (pick which approved reseller to act as)
- Full integration: store, sidebar, top-bar, command-menu, i18n, app-shell
- Mobile responsive, German labels, no indigo/blue
2026-10-28 23:46:54 +00:00
Z User
ec5e6b1629
feat: instance admin login token + cleanup cron (GitHub Action)
...
Instance admin login:
- Provisioning generates adminLoginToken (crypto random, 7-day expiry)
- Sends instance-ready email with admin login URL to customer
- Token returned in provisioning response
Cleanup cron:
- .github/workflows/cleanup-cron.yml: daily at 03:00 UTC
- Calls POST /api/aos/instances/cleanup with CRON_SECRET
- Also supports manual trigger (workflow_dispatch)
- Requires GitHub secrets: AOS_URL, CRON_SECRET
2026-10-28 23:37:42 +00:00
Z User
00a3a89263
feat: custom domain flow (request → verify TXT+CNAME → Dokploy attach)
...
- POST /api/aos/instances/[id]/custom-domain: request domain attachment
- Generates verification token (dfm-verify-{random})
- Returns required DNS records (TXT + CNAME) for the client to add
- Validates: no IPs, no wildcards, no platform-owned domains
- PATCH /api/aos/instances/[id]/custom-domain: verify DNS + attach
- Verifies TXT record via DNS-over-HTTPS (dns.google)
- Verifies CNAME points to {subdomain}.dfmpanel.eu
- Attaches domain in Dokploy via createDomain
- Marks instance.domainVerifiedAt
- DELETE: removes custom domain (keeps platform subdomain)
- Instance events logged for each step
2026-10-28 23:11:21 +00:00
Z User
d97dd955d1
feat: client portal actions — Stripe pay + ticket create + license cancel
...
- PortalInvoices: Stripe checkout button (redirects to Stripe Checkout)
- PortalTickets: 'Neues Ticket' dialog (subject, category, priority, message)
- Calls POST /api/aos/tickets (auto-routes to agency if parent set)
- PortalLicenses: 'Kündigen' button + inline cancel dialog
- Shows trial vs notice period info
- Calls PATCH /api/aos/licenses/[id]/cancel
- Updated PortalData.licenses interface with billing fields
2026-10-28 23:09:54 +00:00
Z User
17e0cfe8a3
trigger: deploy auth + stripe + email + dokploy fix
2026-10-28 23:07:10 +00:00
Z User
617f00b715
fix: rewrite Dokploy client with correct API format (tRPC + x-api-key)
...
- Verified endpoints from @dokploy/mcp source code:
- Auth: x-api-key header (not Authorization: Bearer)
- Base URL: {url}/api
- application.create → needs environmentId (not projectId)
- Git provider saved separately: saveGiteaProvider / saveGithubProvider / saveGitProvider
- Environment vars saved via saveEnvironment
- Deploy is a separate call after create
- Domain attach via domain.create
- Provisioning flow now multi-step:
1. application.create
2. saveGiteaProvider or saveGithubProvider (based on gitRepo URL)
3. saveEnvironment (env vars)
4. application.deploy
5. domain.create (optional, non-fatal)
- Removed database provisioning (Dokploy apps use their own DB via env vars)
- Teardown simplified: deleteDomain → deleteApplication
- Updated instances route + cleanup route to match new API
2026-10-28 23:05:53 +00:00
Z User
970986fef7
feat: email integration (nodemailer) + wire into agency/license flows
...
- src/lib/email.ts: SMTP client with pre-built templates:
- sendAgencyApprovedEmail (reseller approval + discount)
- sendAgencyRejectedEmail (reseller rejection + reason)
- sendLicenseKeyEmail (license key delivery)
- sendTicketCreatedEmail (ticket confirmation)
- Agency approve route: sends approval email after DB update
- Agency reject route: sends rejection email with reason
- License creation route: sends license key email (fire-and-forget)
- Graceful degradation: if SMTP not configured, logs warning + continues
- nodemailer + @types/nodemailer installed
2026-10-28 22:50:42 +00:00
Z User
7a13dad693
feat: Stripe integration — checkout + webhook + subscription lifecycle
...
- src/lib/stripe/index.ts: Stripe client (checkout session + webhook event)
- POST /api/aos/stripe/checkout: create subscription checkout for a license
- POST /api/aos/stripe/webhook: handle events:
- checkout.session.completed → link Stripe customer/subscription to license
- invoice.paid → activate license (remove trial)
- customer.subscription.deleted → cancel license + schedule instance deletion
- invoice.payment_failed → suspend license (dunning)
- Middleware: stripe/webhook is public (Stripe calls it without auth)
- stripe package installed (v23)
2026-10-28 22:48:33 +00:00
Z User
3f90c33c5f
trigger: auth deploy
2026-10-28 22:44:03 +00:00
Z User
17ceefe32a
feat: auth system (middleware + login) + remove .env from git + fix hardcoded token
...
CRITICAL SECURITY FIXES:
- src/middleware.ts: protects all routes except public ones (health, license check, seed-prod)
Redirects unauthenticated users to /login, returns 401 for API routes
- src/app/login/page.tsx: login page with password input
- src/app/api/auth/login: HMAC-signed session cookie (7-day expiry)
- src/app/api/auth/logout: clears session cookie
- Top bar: Abmelden (logout) button now functional
- .env removed from git tracking (secrets no longer in repo)
- seed-prod: hardcoded admin token replaced with env MCP_API_TOKEN or random UUID
- ADMIN_PASSWORD env var required for login (set in Dokploy env)
Public routes (no auth needed):
/api/health, /api/aos/seed-prod, /api/aos/licenses/check, /api/aos/licenses/validate
/api/v1/* (token-auth'd), /api/mcp (token-auth'd), /login
2026-10-28 22:38:39 +00:00
Z User
e7185103f5
f6acc620-0a4c-41b3-9763-6681634541c0
2026-10-28 22:14:58 +00:00
Z User
f2d4241a1c
chore: trigger Gitea webhook deploy
2026-10-28 21:56:38 +00:00
Z User
2251209935
fix: allow seed-prod without SEED_ADMIN_KEY when DB is empty (bootstrap mode)
2026-10-28 21:48:38 +00:00
Z User
b5d3df6d7c
feat: production-safe seed endpoint (SEED_ADMIN_KEY protected, no child_process)
...
- POST /api/aos/seed-prod: populates DB with modules + companies + licenses
- Requires X-Seed-Key header matching SEED_ADMIN_KEY env
- Runs Prisma directly (no bun dependency, no child_process)
- Activates all 12 core modules (crm, leads, projects, licenses, etc.)
- Creates restov1 core + 4 modules + demo license
- Creates admin API token for MCP access
2026-10-28 21:09:56 +00:00
Z User
25599a5516
feat: Graphify build worker endpoints + UI trigger
...
- POST /api/aos/instances/[id]/graph-build: trigger or get build command
- POST /api/aos/instances/[id]/graph-status: worker callback (ok/error)
- GET /api/aos/graphify-health: check if Graphify service is up
- Instance detail: 'Graph neu erstellen' button (visible when demo_active/active)
- Graceful degradation: if GRAPHIFY_URL not set, returns build command for external worker
2026-10-28 19:38:28 +00:00
Z User
7d94fe53ad
feat: Graphify integration — tenant codebase graph + support AI augmentation
...
- src/lib/graphify.ts: MCP HTTP client (query, god nodes, shortest path, stats)
- Instance provisioning: fire-and-forget graph build after deploy
- MCP route: 4 new tools (query_tenant_codebase, get_tenant_god_nodes, get_tenant_graph_stats, find_code_path)
- Support ticket summarize: graph query before AI summary (codebase context)
- Instance detail UI: Graphify status section (queued/done/failed)
- .env: GRAPHIFY_URL + GRAPHIFY_API_KEY (commented, opt-in)
2026-10-28 19:23:57 +00:00
Z User
ada029d500
f797e8cd-c1b7-4c35-9432-11571c257b97
2026-10-28 19:14:01 +00:00
Z User
246ddac9e7
d3eef89b-6729-4b4f-9215-6867bf46fb68
2026-10-28 19:04:17 +00:00
Z User
dd0b88b6eb
fix: remove useTheme from Sonner (useContext null crash on global-error prerender)
2026-10-28 19:03:44 +00:00
Z User
d71bd76e23
849e2d1f-02aa-4e33-a3e6-0fb0d0849820
2026-10-28 18:45:13 +00:00
Z User
f7ce0e5fbe
fix: use webpack build instead of Turbopack (global-error prerender bug)
2026-10-28 18:45:00 +00:00
Z User
a6793a72d2
f5b2bd54-f732-442f-9c7b-97282c447ff6
2026-10-28 18:24:18 +00:00
Z User
945ce598d2
fix: add self-contained global-error.tsx (useContext null during prerender)
2026-10-28 18:24:07 +00:00
Z User
c2b296d605
5d943d38-7d31-4618-80e3-0fb9b18d348a
2026-10-28 17:51:16 +00:00
Z User
d0f7d9d562
fix: FuseButton named import in fuse-cta (build error fix)
2026-10-28 17:50:48 +00:00
Z User
58521ca03a
Merge remote-tracking branch 'origin/main'
...
# Conflicts:
# db/custom.db
# src/components/FuseButton.tsx
# src/components/SlideCommit.tsx
2026-10-28 17:41:22 +00:00
Z User
dbcd79fbb1
2a180f92-c37d-4d06-a523-4063bf3b4772
2026-10-28 17:10:07 +00:00
Z User
f341ba4525
0387f96f-afab-4bb0-abca-ccad372cb7d7
2026-10-28 17:02:47 +00:00
Z User
8c34778db3
0bb384e7-e18c-49c5-b7ef-fe73701ab6ab
2026-10-28 17:00:06 +00:00
Z User
c4d338ee48
c9ca35d6-b826-45a9-8f06-c335add2490d
2026-10-28 16:47:42 +00:00
Z User
c6adc67479
4413045f-d05e-4d7a-a70d-81d6be253c85
2026-10-28 16:37:26 +00:00
Z User
762f3d7373
a6c0f3de-eeb0-4d76-a57f-f600dd133c06
2026-10-28 15:39:30 +00:00
Z User
7eba4cfaeb
feat: SwipeRow integrated into Leads Finder review queue
...
Pending leads now render as SwipeableLeadCard (ReactBits SwipeRow):
- Swipe right: approve (green action)
- Swipe right (second action): snooze (gray)
- Swipe left: reject (dismiss action)
- Full swipe with commit at 55% threshold
- Score badge + company name + website + city + score label
- Selecting a lead opens the detail panel
Non-pending leads (approved/rejected/converted) keep the simple
button card for review history.
0 TS errors, ESLint clean, 0 console errors.
2026-10-28 03:08:54 +00:00
Z User
4618d96201
fix: Hydration mismatch — mount gate + suppressHydrationWarning
...
Root cause: Radix UI components (DropdownMenu, Popover, Dialog) generate
element IDs via React useId() which differ between server and client
render passes. This causes a hydration mismatch warning in the console.
Fix:
1. Added hydration gate in AppShell: render a minimal skeleton on first
server render, then mount the full interactive UI after useEffect.
This ensures Radix IDs are only generated on the client.
2. Added suppressHydrationWarning to <body> (already on <html>).
This is the official next-themes + Radix pattern.
The skeleton shows: sidebar placeholder + empty header + footer.
After mount (~1 frame), the full UI renders with all interactive components.
Verified: 0 hydration errors, 0 console errors, 0 page errors.
0 TS errors, ESLint clean.
2026-10-28 02:46:22 +00:00
Z User
37e976a732
feat: ReactBits micro components integration
...
Installed 6 ReactBits micro components (src/components/):
- SwipeRow: swipe-to-action cards (lead approve/reject/snooze)
- CometDial: circular dial selector (future: dashboard KPI selector)
- CodeSlots: code input slots (future: API token confirmation)
- FuseButton: fuse-animated CTA with undo window
- SlideCommit: slide-to-confirm (timesheet week lock)
- HoldButton: hold-to-confirm (contract sign, dangerous actions)
Integrated into views:
- Timesheet: SlideCommit replaces 'Woche sperren' button
- Contracts: HoldButton replaces 'E-Signatur anfordern' (hold 1.5s to sign)
- Recurring: FuseButton replaces 'Jetzt ausführen' (with undo window)
- Leads: SwipeableLeadCard created (swipe to approve/reject/snooze)
Created wrapper components:
- swipeable-lead-card.tsx: SwipeRow wrapper for lead cards
- hold-to-confirm.tsx: HoldButton wrapper with loading state
- fuse-cta.tsx: FuseButton wrapper with toast feedback
- slide-to-lock.tsx: SlideCommit wrapper for GoBD week lock
0 TS errors, ESLint clean, no console errors.
2026-10-28 02:36:53 +00:00
Z User
21e112e5cb
5355f1bc-7891-4c2d-b8b0-203f174ee94e
2026-10-28 01:36:28 +00:00
Z User
aa6365e373
feat: GitHub/Gitea webhook receiver + .env.example (PRD §6.3)
...
GitHub webhook receiver (POST /api/aos/webhooks/github):
- Push events: extracts commit messages, matches #TKT-XXXX or task:<id> references,
adds commit links as task comments, audit-logs
- Pull request events: matches branch name to project (e.g. feature/intranet-portal → project),
audit-logs PR creation
- HMAC signature verification (X-Hub-Signature-256, GITHUB_WEBHOOK_SECRET env)
- Rate limited (10/min), handles ping events gracefully
- Tested: push (3 commits parsed), PR opened (branch→project matching), ping (acknowledged)
.env.example template:
- All config keys documented with comments
- Database, encryption, auth, mail, Leads Finder providers
- GitHub webhook secret, bank PSD2, storage dir
- German defaults, production notes
0 TS errors, ESLint clean.
2026-10-28 01:30:32 +00:00
Z User
de6573b15e
feat: Invoice PDF + Beleg file upload with content-addressed storage
...
2 new features:
1. Invoice PDF (GET /api/aos/invoices/[id]/pdf)
- Generates German invoice as print-ready HTML (browser → Print to PDF)
- Real agency header (name, legal form, USt-IdNr, register, bank, BIC from settings)
- Customer block, line items table, net/tax/gross totals
- ZUGFeRD/XRechnung badges if applicable
- German number/date formatting (1.234,56 € / 27.10.2026)
- GoBD: no-store cache header
- 3.2KB per invoice, contains RECHNUNG + Gesamt
(Production: Typst for server-side PDF generation per PRD §5.2)
2. Beleg file upload (POST /api/aos/belege/upload)
- Multipart/form-data file upload
- Content-addressed storage (SHA-256 hash, atomic write, dedup)
- Magic number content type detection (PDF, PNG, JPEG, etc.)
- Duplicate detection (same hash → 409)
- GoBD retention (8 years for invoices, 6 for others)
- Audit-logged
- Tested: upload OK, duplicate → 409
0 TS errors, ESLint clean.
2026-10-28 01:24:48 +00:00
Z User
2aa3496a90
feat: Leads Finder discovery + WordPress license validate + file storage
...
3 new PRD features:
1. Leads Finder discovery (PRD §6.2 Stage 1: Discover)
- Real SerpAPI integration (Google Maps local search)
- Real Tavily integration (web search API)
- Real Firecrawl integration (search + scrape)
- Returns company name, website, address, phone, description
- API key required (503 with hint if not configured)
- Rate limited, Zod validated, audit-logged
- POST /api/aos/leads/discover
2. WordPress-compatible license validation (PRD §6.4)
- POST /api/aos/licenses/validate
- WordPress plugin updater response format
- Domain auto-activation with max check
- Offline grace period (14 day default, configurable)
- Status checks: active/suspended/expired/revoked
- Rate limited (30/min), Zod validated, audit-logged
- Tested: active→valid✓, invalid→404, expired→403, suspended→403
3. Content-addressed file storage (PRD §5.5)
- src/lib/storage.ts
- SHA-256 hash addressing with sharded dirs (first 2 chars)
- Atomic writes (temp file → rename)
- Hash verified on read (tamper detection)
- Deduplication (same content = same hash = one file)
- Content type detection from magic numbers (PDF, PNG, JPEG, GIF, WebP, ZIP)
- storeFile(), readFile(), fileExists(), deleteFile()
0 TS errors, ESLint clean.
2026-10-27 23:49:25 +00:00
Z User
e45b68bb8b
feat: IMAP mail sync with thread-to-contact matching (PRD §6.1)
...
Real IMAP connection via imapflow library:
- Connects to IMAP server (IMAPFlow, TLS on port 993)
- Fetches recent messages (configurable limit, default 20)
- Extracts: from, fromEmail, subject, date, snippet (200 chars)
- Thread-to-contact matching (PRD §6.1):
1. Match sender email against persons table
2. If no person match, extract domain and match against company.website
3. Returns matchedCompany + matchedPerson for each email
- Audit-logged (action: crm.mailsync:imap)
- Zod validated (host, port, user, password, folder, limit)
- 502 on IMAP connection failure with detail
- 400 on validation failure
Tested: invalid creds → 502 'IMAP connection failed', missing host → 400
2026-10-27 22:50:50 +00:00
Z User
7acc0c5451
chore: sync files after PRD gap fixes (Zod, rate-limit, custom-fields, CSP, boundary)
...
5 PRD gaps fixed:
1. Zod validation on all API inputs (§5.2) — 26 files, 27 safeParse
2. Rate limiting on public endpoints (§5.6) — 6 scopes, 7 endpoints
3. Custom fields JSONB with schema (§5.5) — 2 models, 10 seed defs
4. CSP + security headers (§5.6) — 7 headers via next.config.ts
5. ESLint module boundary rule (§5.4) — no-restricted-imports
0 TS errors, ESLint clean.
2026-10-27 22:48:01 +00:00
Z User
f942c65e0d
feat: ESLint module boundary rule (PRD §5.4)
...
Enforced module boundaries via no-restricted-imports:
(a) Views must not import other views directly (use shared primitives)
(b) Infrastructure code must not import UI views
(c) Portal-shell is isolated from agency views
Pattern from Haben: strict module separation, cross-module access only via index.ts
2026-10-27 22:21:30 +00:00
Z User
9bf94ee79a
feat: CSP + security headers (PRD §5.6)
...
next.config.ts headers():
- Content-Security-Policy: default-src 'self', frame-ancestors 'none', form-action 'self'
- X-Content-Type-Options: nosniff
- X-Frame-Options: DENY (clickjacking prevention)
- Referrer-Policy: strict-origin-when-cross-origin
- Permissions-Policy: camera/microphone/geolocation/payment disabled
- Strict-Transport-Security: HSTS 2 years + preload
- API routes: Cache-Control no-store (PRD: 'no-store on private files')
Verified: all 7 security headers present on every page + API response.
2026-10-27 22:20:26 +00:00
Z User
81acd9df7a
feat: Custom fields — JSONB with schema per entity (PRD §5.5)
...
Models: CustomFieldDef (schema definitions) + CustomFieldValue (entity values)
- Per entity type: company, person, deal, project, invoice, ticket, contract
- Field types: string, number, boolean, date, select, multiselect
- Options for select/multiselect stored as JSON
- Unique constraint: (entityType, key) for definitions, (entityType, entityId, fieldDefId) for values
API /api/aos/custom-fields:
- GET: list all definitions (+ filter by entityType)
- POST: create definition (Zod validated, lowercase_snake_case key, unique check)
- PATCH: set value on entity (upsert pattern)
Seed: 10 field definitions across 6 entity types
- company: branche, mitarbeiterzahl, umsatzklasse
- person: entscheider, kontaktweg
- deal: wettbewerber, entscheidungsgrund
- project: prioritaet
- invoice: kostenstelle
- ticket: auswirkung
Verified: 10 defs, 3 company fields, duplicate→409, invalid key→400
2026-10-27 22:19:25 +00:00
Z User
d5dc2a1832
feat: Rate limiting on all public endpoints (PRD §5.6)
...
In-memory rate limiter with configurable limits per scope:
- auth: 5 req/min (login, passkey — future)
- public: 20 req/min (setup mail test, public forms)
- api: 100 req/min (public REST API v1)
- license: 30 req/min (license validate/activate — future)
- mcp: 60 req/min (MCP server)
- webhook: 10 req/min (webhook test trigger)
Applied to 7 endpoints:
- /api/mcp (MCP JSON-RPC — 60/min)
- /api/v1/companies (public REST — 100/min)
- /api/v1/invoices (public REST — 100/min)
- /api/v1/licenses (public REST — 100/min)
- /api/v1/webhooks/test (webhook test — 10/min)
- /api/aos/setup/test-mail (public form — 20/min)
429 response with Retry-After + X-RateLimit headers.
Recreated /api/v1/webhooks/test/route.ts (lost in git merge).
2026-10-27 21:33:43 +00:00
Z User
2614ce4e3d
feat: Zod validation on all API inputs (PRD §5.2)
...
26 files with Zod schemas, 27 safeParse calls.
All POST/PATCH handlers now validate input:
- Missing required fields → 400 with structured error
- Invalid types (string vs number) → 400
- Out-of-range values (probability >100, negative amounts) → 400
- Valid data still works (behavior preserved)
Pattern: schema.safeParse(await req.json()) → 400 on failure
2026-10-27 21:29:51 +00:00
Z User
3d56770669
feat: Docker deployment + backup/restore + README
...
Production deployment (PRD §5.7):
- Dockerfile: multi-stage build (deps → build → runner), healthcheck
- docker-compose.yml: app + backup container + Caddy HTTPS proxy
- Backup container: daily SQLite backup + SHA-256 checksum
- Caddy: automatic HTTPS reverse proxy
- Volumes: db, data, backups, caddy-data
- deploy/backup.sh: timestamped backup + checksum + retention cleanup
- deploy/restore.sh: checksum verification + pre-restore backup
- README.md: quick start (Docker + dev), architecture, modules, compliance, MCP
Verified:
- Backup script: creates aos_20261027.db + .sha256 ✓
- TypeScript: 0 errors, ESLint clean
2026-10-27 20:55:09 +00:00
Z User
01be2e7820
docs: Complete CLAUDE.md with 29-tool MCP reference + usage examples
...
Final project status:
- 328 files, 26.357 lines of code
- 23 views + client portal (5 tabs)
- 69 API routes (30 AOS + 5 public v1 + 1 MCP + 1 health + 32 nested)
- 39 Prisma models
- 29 MCP tools (16 read + 13 write) for Claude Code
- 0 TypeScript errors, ESLint clean
- All 30 AOS endpoints + 6 public endpoints returning correct status codes
- Health endpoint: ok, DB connected
2026-10-27 20:49:50 +00:00
Z User
8eb435fff4
594213c8-60c3-4a3a-b1d7-2256b4af66ea
2026-10-27 20:46:57 +00:00
Z User
97426e0ca8
feat: 29 MCP tools — full agency read+write coverage
...
5 new MCP read tools (29 total: 16 read + 13 write):
- get_contracts: Verträge (AVV, NDA, SLA, Werkvertrag) with status + value
- get_projects: Projects with progress, budget, task/time counts
- get_timesheet: Weekly timesheet grid with lock status
- get_notifications: All alerts (overdue invoices, expiring licenses, SLA breaches)
- get_calendar: Upcoming deadlines (30-day look-ahead across all modules)
Claude Code can now read:
companies, pipeline, invoices, leads, dashboard, tickets, buchhaltung,
anlagen, kassenbuch, belege, finanzamt, contracts, projects, timesheet,
notifications, calendar (16 read tools)
And write:
approve lead, create ticket/deal/task/invoice/buchung/beleg/pauschale/kassenbuch,
log time, finalize invoice, run recurring, update deal stage (13 write tools)
All 29 tools tested and verified working.
2026-10-27 20:46:31 +00:00
Z User
9c226c471c
feat: 24 MCP tools (full accounting write) + Copilot instructions
...
4 new MCP write tools (24 total: 11 read + 13 write):
- create_buchung: SKR04 Buchungssatz (Soll an Haben, doppelte Buchführung)
- create_beleg: Register receipt with SHA-256 hash, GoBD retention
- create_pauschale: Homeoffice/Kilometer/Verpflegung with auto-computed amounts
(€6.92/day, €0.30/km, €14/€24/€28 per EStG)
- create_kassenbuch_entry: Cash book entry (§ 146 AO, immutable, running balance)
Added .github/copilot-instructions.md
Fixed TypeScript strict-mode issues with MCP args type safety
Claude Code can now:
- Read: companies, pipeline, invoices, leads, dashboard, tickets, buchhaltung, anlagen, kassenbuch, belege, finanzamt
- Write: deals, tasks, time, invoices (+ finalize), recurring, leads (approve), tickets, buchungen, belege, pauschalen, kassenbuch
2026-10-27 20:30:16 +00:00
Z User
ab9fd10b5e
feat: Claude Code auto-detect (.mcp.json) + 20 MCP tools + health endpoint
...
Claude Code integration:
- .mcp.json at repo root for auto-detection (uses seed admin token)
- CLAUDE.md project instructions (commands, architecture, rules)
- Pre-seeded admin token: aos_admin_seed_token_for_claude_code_2026
- Scopes: all read + all write + mcp:read + mcp:write
- Works out of the box after bun run src/lib/seed.ts
5 new MCP read tools (20 total: 11 read + 9 write):
- get_buchhaltung: SKR04 Konten, Journal, Saldenliste, EÜR summary
- get_anlagen: Anlagenverzeichnis with AfA, book values, GWG
- get_kassenbuch: Cash book entries, running balance
- get_belege: Receipts with SHA-256 content hashes
- get_finanzamt: VAT returns, Jahreserklärungen, Jahresarchive
Fix: api-auth regex updated to allow underscores in tokens (aos_[a-z0-9_]+)
Health endpoint: GET /api/health (DB connection + version + uptime)
2026-10-27 20:23:50 +00:00
Z User
1a3241971c
dd04e5e9-8a88-45d0-b3b8-14caa1f684dc
2026-10-27 19:51:03 +00:00
Z User
7142ffbe6c
feat: MCP admin-level tools — Claude Code can manage the full agency
...
7 new WRITE MCP tools (15 total):
- create_deal: create deals with value, stage, probability
- update_deal_stage: move deals through the pipeline
- create_task: create tasks with priority, assignee, estimate
- log_time: log billable time entries with rate
- create_invoice: create draft invoices with line items
- finalize_invoice: lock + set to sent (GoBD Festschreibung)
- run_recurring: trigger recurring invoice scheduler + license suspend
Added scopes: crm.deal:write, finance.invoice:write, finance:write, projects:write
Claude Code with an admin token can now:
- Search companies, view pipeline, check invoices (read)
- Create deals, tasks, log time, create+finalize invoices (write)
- Run the recurring scheduler (admin)
- Approve leads, create tickets (existing write tools)
All actions audit-logged with actor 'mcp-agent'
2026-10-27 19:50:43 +00:00
Z User
01214ac5db
fix: Remove agency-internal details from onboarding (company secret)
...
Onboarding overlay:
- Removed '20 Module · 21 API-Endpunkte · MCP-Server · Client-Portal'
- Removed '8 MCP Tools · HMAC-signed Webhooks · OpenAPI 3.0'
- Removed 'z-ai-web-dev-sdk, server-side' technical reference
- Removed 'Real CAMT.053 Parser · ELSTER XML · SLA-Tracking'
- Removed 'Real IP Evidence · 3 Sprachen'
- Removed 'Hash-Kette Audit'
- Renamed 'API & MCP Server' → 'Schnittstellen' (generic)
- Renamed 'Client-Portal' → 'Kunden-Portal'
Onboarding checklist:
- Removed 'API-Token erstellen' item
- Replaced with 'Fristen-Kalender öffnen' (more useful)
- Removed '(UStVA)' from Buchhaltung label
- Changed 'Client-Portal' → 'Kunden-Portal'
These are internal platform details that clients should never see.
2026-10-27 19:23:49 +00:00
Z User
7f7f364183
93dd2eec-4a55-4753-8474-c1bbde1564e9
2026-10-27 18:52:56 +00:00
Z User
07147a758c
feat: DATEV Export (EXTF v5.0) + iCal Fristen feed + UI buttons
...
DATEV Export:
- Real DATEV EXTF Buchungsstapel format (v700, semicolon-separated)
- Header line with metadata (consultant, client, year, currency)
- Data rows: Soll, Haben, Betrag, Belegdatum, Text, Belegnr, USt%
- Also supports simple CSV format
- Audit-logged
- Download button in SKR04/Buchführung tab
iCal Fristen Feed:
- Real .ics calendar feed (RFC 5545 compliant)
- Aggregates ALL deadlines: UStVA, contracts, licenses, assets, projects, invoices
- 23 events from 6 modules
- Subscribe via webcal:// URL in Apple/Google/Outlook Calendar
- Download button in SKR04/Buchführung tab
0 TypeScript errors, ESLint clean
2026-10-27 18:51:55 +00:00
Z User
c184513b2a
cc9d365d-6d71-4dbc-b48a-6bea87eb9854
2026-10-27 18:14:17 +00:00
Z User
6cbf0b2879
feat: Full company accounting — SKR04, doppelte Buchführung, GoBD Festschreibung
...
Haben-cloned features for complete company accounting:
SKR04 Kontenrahmen (21 Konten):
- Bestandskonten (Aktiv/Passiv): Bank, Kasse, EDV-Anlagen, Verbindlichkeiten
- Erlöskonten: Erlöse 19% USt, Fremdleistungen
- Aufwandskonten: Bezogene Leistungen, Bürobedarf, EDV-Kosten, Reisekosten, Löhne
- Steuerkonten: USt 19%/7%, abziehbare Vorsteuer
Doppelte Buchführung (Buchungssatz):
- Soll an Haben booking system
- Journal with lückenlose Nummerierung (BUC-2026-XXXX)
- Saldenliste (account balances per Konto)
- GoBD Festschreibung (immutable via SHA-256 hash)
- Reverse Charge and §19 UStG (Kleinunternehmer) flags
EÜR (Einnahmen-Überschuss-Rechnung):
- Anlage EÜR with AVEÜR line numbers
- § 4 Abs. 3 EStG computation
- Gewinn: €14.506 (2026)
Jahresabschluss (GoBD):
- Immutable year-end archive with SHA-256 hash chain
- Links to previous year (2025 → 2026)
- Festschreibung of all bookings in the year
- Aufbewahrungsfrist: 8 Jahre (GoBD) / 10 Jahre (§ 147 AO)
Jahreserklärungen:
- USt-Erklärung (yearly, more lines than monthly UStVA)
- Anlage EÜR, Einkommensteuer, Gewerbesteuer
- ELSTER submission tracking
Seed: 21 Konten, 7 Buchungssätze, 9 EÜR entries, 2 Jahreserklärungen, 1 Jahresarchiv
2026-10-27 18:13:04 +00:00
Z User
0d0fa6b5e1
bbb245ef-c23d-4d22-87ba-d5366d9def16
2026-10-27 17:41:53 +00:00
Z User
1573931c0f
feat: Haben-clone + client portal privacy fix
...
Client Portal privacy (şirket sırrı):
- Removed PRD references from client-facing text
- Removed 'Projekt-isolierter Zugriff' technical term
- Changed to 'Sichere Verbindung' / 'Sicher geschützt'
- Onboarding overlay only shows to agency users (not portal)
Haben-cloned features (Almanya/EU muhasebe uyumu):
- Belege: content-addressed receipts (SHA-256 hash, GoBD retention 8/6 years)
- Pauschalen: Homeoffice (€6.92/day), Kilometer (€0.30/km), Verpflegung (€14/€24/€28)
- EStG § 4 Abs. 5, § 9 Abs. 1 compliant rates (2026)
- Anlagen & AfA: Anlagenverzeichnis with linear depreciation
- GWG (≤€800 Sofortabschreibung, § 6 Abs. 2 EStG)
- Sammelposten (€251-€1000, § 6 Abs. 2a EStG, 5 years)
- Annual AfA computation + accumulated AfA + book value
- Kassenbuch: cash book (§ 146 AO, § 22 UStG)
- Immutable (GoBD), running balance, audit-logged
- Gapless numbering (KAS-2026-XXXX)
Seed data: 5 Belege, 7 Pauschalen, 5 Anlagen, 5 Kassenbuch entries
TypeScript: 0 errors | ESLint: clean
2026-10-27 17:40:47 +00:00
Z User
3cb7532417
d7b304d4-c8e0-431e-b1b1-fcc645d323e1
2026-10-27 17:15:56 +00:00
Z User
49377bb2de
feat: CSV Import for CRM (PRD §6.1: CSV import/export with mapping)
...
- Real RFC 4180 CSV parser (handles quoted fields, escaped quotes, newlines)
- 3-step import dialog: upload → map columns → result
- Column auto-detection (name/firma/company)
- Duplicate detection (name + website)
- Creates companies + optional persons
- Import audit-logged
- Result summary: created, skipped, errors
2026-10-27 17:15:00 +00:00
Z User
25451d77eb
f2b43822-37b9-490c-b8bb-0888d61227a3
2026-10-27 16:53:07 +00:00
Z User
597bfbc3d8
feat: Recurring invoices + license suspend on dunning level 3 (PRD §6.4/§6.6)
...
- Recurring API: list contracts needing invoicing + run endpoint
- Auto-generate draft invoices for Wartung/SLA + Dienstvertrag contracts
- Automatic license suspension at dunning level 3 (PRD §6.4)
- Recurring billable expenses tracking
- MRR/ARR computation from contracts + expenses
- Prisma: added Contract.company + Expense.company relations
- Scheduler info (pg-boss monthly cron in production)
2026-10-27 16:51:58 +00:00
Z User
c8b4be55f3
e558113a-99ae-4e5a-9db1-dcd3475a4e04
2026-10-27 16:28:08 +00:00
Z User
6c42c6525a
feat: Data Management (DSGVO Art. 15/20/30 — export, inventory, retention)
...
- Data Management API: inventory (Art. 30 Verarbeitungsverzeichnis) + export
- JSON export with SHA-256 checksum (GoBD Jahresarchiv)
- CSV export (DATEV/Excel-compatible)
- Export history (audit-logged)
- Retention periods (8/6 years per GoBD)
- Art. 17 erasure notice (pseudonymization, legal precedence)
- 159 records across 10 categories with legal basis per category
2026-10-27 16:27:42 +00:00
Z User
1dd2563172
Merge branch 'main' of https://github.com/cetinmustafa83/aos
...
# Conflicts:
# .env
# .gitignore
# Caddyfile
# bun.lock
# components.json
# db/custom.db
# eslint.config.mjs
# next.config.ts
# package.json
# postcss.config.mjs
# prisma/schema.prisma
# public/logo.svg
# public/manifest.json
# public/robots.txt
# src/app/api/aos/accounting/bank/[id]/match/route.ts
# src/app/api/aos/accounting/bank/import/route.ts
# src/app/api/aos/accounting/route.ts
# src/app/api/aos/accounting/vat/[id]/submit/route.ts
# src/app/api/aos/api-tokens/[id]/revoke/route.ts
# src/app/api/aos/api-tokens/route.ts
# src/app/api/aos/audit/route.ts
# src/app/api/aos/calendar/route.ts
# src/app/api/aos/contracts/[id]/sign/route.ts
# src/app/api/aos/contracts/route.ts
# src/app/api/aos/crm/companies/[id]/route.ts
# src/app/api/aos/crm/deals/route.ts
# src/app/api/aos/crm/route.ts
# src/app/api/aos/dashboard/route.ts
# src/app/api/aos/estimates/[id]/accept/route.ts
# src/app/api/aos/estimates/[id]/convert/route.ts
# src/app/api/aos/estimates/route.ts
# src/app/api/aos/expenses/[id]/convert/route.ts
# src/app/api/aos/expenses/route.ts
# src/app/api/aos/finance/[id]/finalize/route.ts
# src/app/api/aos/finance/route.ts
# src/app/api/aos/kb/generate/route.ts
# src/app/api/aos/kb/route.ts
# src/app/api/aos/leads/[id]/route.ts
# src/app/api/aos/leads/convert/route.ts
# src/app/api/aos/leads/explain/route.ts
# src/app/api/aos/leads/route.ts
# src/app/api/aos/licenses/route.ts
# src/app/api/aos/modules/route.ts
# src/app/api/aos/notifications/route.ts
# src/app/api/aos/portal/approvals/[id]/decide/route.ts
# src/app/api/aos/portal/companies/[id]/notifications/route.ts
# src/app/api/aos/portal/companies/[id]/route.ts
# src/app/api/aos/portal/companies/route.ts
# src/app/api/aos/projects/[id]/tasks/route.ts
# src/app/api/aos/projects/[id]/time/route.ts
# src/app/api/aos/projects/route.ts
# src/app/api/aos/reporting/route.ts
# src/app/api/aos/search/route.ts
# src/app/api/aos/seed/route.ts
# src/app/api/aos/settings/route.ts
# src/app/api/aos/setup/test-mail/route.ts
# src/app/api/aos/tasks/[id]/comments/route.ts
# src/app/api/aos/tickets/[id]/reply/route.ts
# src/app/api/aos/tickets/[id]/summarize/route.ts
# src/app/api/aos/tickets/route.ts
# src/app/api/aos/timesheet/route.ts
# src/app/api/aos/webhooks/route.ts
# src/app/api/mcp/route.ts
# src/app/api/route.ts
# src/app/api/v1/companies/route.ts
# src/app/api/v1/invoices/route.ts
# src/app/api/v1/licenses/route.ts
# src/app/api/v1/openapi/route.ts
# src/app/globals.css
# src/app/layout.tsx
# src/app/page.tsx
# src/components/aos/app-shell.tsx
# src/components/aos/command-menu.tsx
# src/components/aos/company-drawer.tsx
# src/components/aos/create-deal-dialog.tsx
# src/components/aos/footer.tsx
# src/components/aos/invoice-dialog.tsx
# src/components/aos/locale-switcher.tsx
# src/components/aos/mobile-bottom-nav.tsx
# src/components/aos/notifications-bell.tsx
# src/components/aos/onboarding-checklist.tsx
# src/components/aos/onboarding-overlay.tsx
# src/components/aos/portal-shell.tsx
# src/components/aos/primitives.tsx
# src/components/aos/sidebar-nav.tsx
# src/components/aos/top-bar.tsx
# src/components/aos/views/accounting.tsx
# src/components/aos/views/api.tsx
# src/components/aos/views/audit.tsx
# src/components/aos/views/calendar.tsx
# src/components/aos/views/contracts.tsx
# src/components/aos/views/crm.tsx
# src/components/aos/views/dashboard.tsx
# src/components/aos/views/estimates.tsx
# src/components/aos/views/expenses.tsx
# src/components/aos/views/finance.tsx
# src/components/aos/views/global-settings.tsx
# src/components/aos/views/kb.tsx
# src/components/aos/views/leads.tsx
# src/components/aos/views/licenses.tsx
# src/components/aos/views/projects.tsx
# src/components/aos/views/reporting.tsx
# src/components/aos/views/settings.tsx
# src/components/aos/views/setup-wizard.tsx
# src/components/aos/views/support.tsx
# src/components/aos/views/timesheet.tsx
# src/components/theme-provider.tsx
# src/components/theme-toggle.tsx
# src/components/ui/accordion.tsx
# src/components/ui/alert-dialog.tsx
# src/components/ui/alert.tsx
# src/components/ui/aspect-ratio.tsx
# src/components/ui/avatar.tsx
# src/components/ui/badge.tsx
# src/components/ui/breadcrumb.tsx
# src/components/ui/button.tsx
# src/components/ui/calendar.tsx
# src/components/ui/card.tsx
# src/components/ui/carousel.tsx
# src/components/ui/chart.tsx
# src/components/ui/checkbox.tsx
# src/components/ui/collapsible.tsx
# src/components/ui/command.tsx
# src/components/ui/context-menu.tsx
# src/components/ui/dialog.tsx
# src/components/ui/drawer.tsx
# src/components/ui/dropdown-menu.tsx
# src/components/ui/form.tsx
# src/components/ui/hover-card.tsx
# src/components/ui/input-otp.tsx
# src/components/ui/input.tsx
# src/components/ui/label.tsx
# src/components/ui/menubar.tsx
# src/components/ui/navigation-menu.tsx
# src/components/ui/pagination.tsx
# src/components/ui/popover.tsx
# src/components/ui/progress.tsx
# src/components/ui/radio-group.tsx
# src/components/ui/resizable.tsx
# src/components/ui/scroll-area.tsx
# src/components/ui/select.tsx
# src/components/ui/separator.tsx
# src/components/ui/sheet.tsx
# src/components/ui/sidebar.tsx
# src/components/ui/skeleton.tsx
# src/components/ui/slider.tsx
# src/components/ui/sonner.tsx
# src/components/ui/switch.tsx
# src/components/ui/table.tsx
# src/components/ui/tabs.tsx
# src/components/ui/textarea.tsx
# src/components/ui/toast.tsx
# src/components/ui/toaster.tsx
# src/components/ui/toggle-group.tsx
# src/components/ui/toggle.tsx
# src/components/ui/tooltip.tsx
# src/hooks/use-fetch.ts
# src/hooks/use-i18n.ts
# src/hooks/use-mobile.ts
# src/hooks/use-toast.ts
# src/lib/api-auth.ts
# src/lib/db.ts
# src/lib/format.ts
# src/lib/i18n.ts
# src/lib/seed.ts
# src/lib/utils.ts
# src/lib/webhook.ts
# src/store/aos.ts
# tailwind.config.ts
# tsconfig.json
2026-10-27 12:24:25 +00:00
Z User
fa8dd46571
refactor: professional code quality audit
...
- Fix all TypeScript compilation errors (0 errors in src/)
- Add try/catch error handling to ALL API routes (38 handlers)
- Fix empty catch blocks (api-auth.ts now logs warnings)
- Add aria-labels to all icon-only buttons (WCAG 2.1 AA)
- Fix Prisma type mismatches (OR filter, Person.companyId, Estimate.projectId, Ticket.createdAt)
- Fix webhook PATCH route (moved to [id]/route.ts)
- Fix mobile-bottom-nav type safety
- Fix KB route where-clause type
- Fix test-mail banner null vs undefined
- Fix task comment fetch: add cancellation + error toast
- ESLint: 0 errors, 0 warnings
- 175 files, 24.741 lines of code
2026-10-27 12:23:32 +00:00
Z User
969202764a
Initial commit
2026-10-27 06:25:53 +00:00
Z User
799d7317a8
chore: ensure .env.local is gitignored
2026-10-27 01:06:48 +00:00
Z User
ced089c1fb
AOS — Agency Operating System (complete build)
...
20+ module self-hosted agency platform per PRD v1.0:
Modules:
- Dashboard (KPIs, pipeline funnel, audit log, onboarding checklist)
- CRM (kanban pipeline, companies, persons, DSGVO consent, company drawer)
- Leads Finder (evidence-based audits, AI explanation via z-ai-web-dev-sdk)
- Angebote/Estimates (quotes → accept → project → invoice)
- Projekte (tasks, time tracking, budgets, task detail drawer with comments)
- Zeiterfassung (weekly timesheet grid, PM lock, GoBD-compliant)
- Support (tickets, AI summarize + reply suggestions, SLA timers)
- Lizenzen (issued licenses, Ed25519 tokens, activation tracking, renewal register)
- Verträge (Werkvertrag, AVV Art.28 DSGVO, NDA, SLA, e-signature with real IP)
- Ausgaben (billable expenses, recurring, DATEV export, convert to invoice)
- Finanzen (invoices, E-Rechnung ZUGFeRD/XRechnung, gapless numbering)
- Buchhaltung (USt-Voranmeldung Kennzahlen 81/86/66/83/37, EÜR, CAMT.053 parser, ELSTER XML)
- Audit-Protokoll (GoBD hash-chain, before/after diffs)
- Wissensdatenbank (versioned articles, AI article drafting)
- API & Webhooks (scoped tokens SHA-256 hashed, HMAC-SHA256 webhooks, OpenAPI 3.0)
- MCP Server (8 JSON-RPC tools for Claude/ZeroClaw agents)
- Einstellungen (typed settings, i18n DE/EN/TR)
- Erweiterungen (module toggles, compliance checklist)
- Setup-Wizard (7-step guided installer)
- Fristen (unified deadline calendar across all modules)
- Reporting (pipeline, utilization, MRR/ARR, activity dashboards)
Client Portal (project-scoped):
- Welcome banner, notifications bell, approvals with IP evidence
- Invoices, tickets, licenses views
Platform:
- PWA installable (manifest.json, mobile bottom nav)
- Dark mode verified across all views
- i18n DE/EN/TR with instant switching
- Onboarding tour (8 steps) + dashboard checklist
- 3 AI flows (leads explanation, ticket summarize/reply, KB drafting)
- Real integrations (TCP mail test, CAMT.053 parser, ELSTER XML, HMAC webhooks)
- No mocks — all real behavior
Tech: Next.js 16, TypeScript, Prisma (SQLite), shadcn/ui, monochrome design
2026-10-27 01:03:27 +00:00
Z User
c71c7e3094
63ef43ec-90ce-4fcf-82b4-abff91b2280a
2026-10-27 01:02:02 +00:00
Z User
8fa25577c0
79ecf134-0188-4613-b691-50e43114247e
2026-10-27 00:54:10 +00:00
Z User
9b5477020c
30f7b0f9-9de3-4087-a91e-c351421922db
2026-10-27 00:35:50 +00:00
Z User
09ca75d36e
0ca22831-efa9-41b6-87bd-e5ee6c344547
2026-10-27 00:00:06 +00:00
Z User
468e7ad123
4146cf4f-64d9-48ee-a4ec-195ac8b92e10
2026-10-26 23:55:58 +00:00
Z User
37cb23d245
115e52dd-042f-444c-9ed4-9bfde9257c45
2026-10-26 23:40:17 +00:00
Z User
7640b78975
7a3ceb05-d8a7-4da8-bc71-27e5e31df3de
2026-10-26 23:23:47 +00:00
Z User
e16d7a748a
f30e7158-97a8-4eaa-b0e8-a28e8a54a3fe
2026-10-26 23:08:38 +00:00