2024 Commits

Author SHA1 Message Date
a2a1151ccb Merge pull request 'dev' (#241) from dev into main
All checks were successful
Build and Release FEDEO / verify (push) Successful in 1m5s
Build and Release FEDEO / build-and-release (push) Successful in 6m29s
Reviewed-on: #241
2026-10-07 17:11:45 +00:00
15e480ee9a fix(build): isolate time tests by Docker build context
All checks were successful
Build and Release FEDEO / verify (push) Successful in 1m0s
Build and Release FEDEO / build-and-release (push) Successful in 6m4s
2026-10-07 19:02:23 +02:00
c2c6ca8fe9 fix(documents): include foreign country in recipient address
Some checks failed
Build and Release FEDEO / verify (push) Successful in 1m3s
Build and Release FEDEO / build-and-release (push) Failing after 1m26s
2026-10-07 18:52:57 +02:00
ac00d2187e feat(accounting): edit cost centres from finalized outgoing documents 2026-10-07 18:50:38 +02:00
29a9ec2242 feat(communication): add chat reactions emojis and images 2026-10-03 17:56:07 +02:00
59538f46b7 fix(communication): enable scrolling in collaboration management 2026-10-03 17:03:03 +02:00
677ae0f4fb feat(time): add span-based attendance tracking under 2.0 2026-10-03 15:55:45 +02:00
4c67ddd908 feat(notifications): add per-tenant notification preferences 2026-10-03 14:50:38 +02:00
efa6ea90a2 fix(communication): display project chat state and refresh room visibility 2026-10-03 14:38:39 +02:00
fdcb9bfc1d feat(accounting): allow cancelling serial invoice executions 2026-10-02 18:48:06 +02:00
daaed01d02 Merge pull request 'dev' (#240) from dev into main
All checks were successful
Build and Release FEDEO / verify (push) Successful in 59s
Build and Release FEDEO / build-and-release (push) Successful in 6m16s
Reviewed-on: #240
2026-10-02 16:30:02 +00:00
7e6c2fbac5 feat(communication): add room visibility and project chat controls
All checks were successful
Build and Release FEDEO / verify (push) Successful in 57s
Build and Release FEDEO / build-and-release (push) Successful in 6m27s
2026-10-02 18:27:02 +02:00
0887863981 feat(communication): integrate collaboration rooms into normal chat 2026-10-02 18:12:03 +02:00
6ff9971ff9 fix(push-admin): show test push delivery errors 2026-10-02 18:03:11 +02:00
e7d6c482ad Merge pull request 'dev' (#239) from dev into main
All checks were successful
Build and Release FEDEO / verify (push) Successful in 58s
Build and Release FEDEO / build-and-release (push) Successful in 6m13s
Reviewed-on: #239
2026-10-02 15:17:16 +00:00
1885bfc521 feat(documents): allow archiving inbox documents
All checks were successful
Build and Release FEDEO / verify (push) Successful in 57s
Build and Release FEDEO / build-and-release (push) Successful in 5m56s
2026-10-02 17:12:05 +02:00
09a002d600 fix(collaboration): configure federation from existing deployment settings 2026-10-02 16:58:57 +02:00
ed305f656c Merge pull request 'dev' (#238) from dev into main
All checks were successful
Build and Release FEDEO / verify (push) Successful in 57s
Build and Release FEDEO / build-and-release (push) Successful in 6m14s
Reviewed-on: #238
2026-10-02 14:18:01 +00:00
d7382e7319 feat(documents): prepare inbox suggestions and add entity assignments
All checks were successful
Build and Release FEDEO / verify (push) Successful in 56s
Build and Release FEDEO / build-and-release (push) Successful in 5m58s
2026-10-02 16:09:04 +02:00
64299843e2 fix(communication): adopt legacy general chat rooms safely 2026-10-02 16:06:31 +02:00
b01cf2c207 fix(updater): retain two verified backup generations 2026-10-02 15:27:07 +02:00
30e932a874 Merge pull request 'dev' (#237) from dev into main
All checks were successful
Build and Release FEDEO / verify (push) Successful in 58s
Build and Release FEDEO / build-and-release (push) Successful in 6m16s
Reviewed-on: #237
2026-10-02 12:51:46 +00:00
23d49f7186 feat(documents): suggest inbox folder and type with AI
All checks were successful
Build and Release FEDEO / verify (push) Successful in 56s
Build and Release FEDEO / build-and-release (push) Successful in 5m54s
2026-10-01 18:11:41 +02:00
07adca417e feat(documents): add inbox document preview modal 2026-10-01 17:54:04 +02:00
0a74e07288 Merge pull request 'fix(scanner): accept Epson empty write probes' (#234) from dev into main
All checks were successful
Build and Release FEDEO / verify (push) Successful in 58s
Build and Release FEDEO / build-and-release (push) Successful in 6m8s
Reviewed-on: #234
2026-10-01 15:36:56 +00:00
f359bfb579 fix(scanner): accept Epson empty write probes
All checks were successful
Build and Release FEDEO / verify (push) Successful in 1m2s
Build and Release FEDEO / build-and-release (push) Successful in 6m0s
2026-09-30 19:57:54 +02:00
4c3de8c942 Merge pull request 'dev' (#233) from dev into main
All checks were successful
Build and Release FEDEO / verify (push) Successful in 58s
Build and Release FEDEO / build-and-release (push) Successful in 6m11s
Reviewed-on: #233
2026-09-30 17:23:15 +00:00
2143ce0933 fix(scanner): normalize Epson collection separators
All checks were successful
Build and Release FEDEO / verify (push) Successful in 55s
Build and Release FEDEO / build-and-release (push) Successful in 6m0s
2026-09-30 19:10:59 +02:00
b585b972f2 fix(scanner): accept Epson inbox GET preflight 2026-09-30 19:04:12 +02:00
49d44d9701 Merge pull request 'dev' (#232) from dev into main
All checks were successful
Build and Release FEDEO / verify (push) Successful in 1m1s
Build and Release FEDEO / build-and-release (push) Successful in 6m18s
Reviewed-on: #232
2026-09-30 15:43:45 +00:00
ca2d14b01e docs(communication): document federation pilot setup and validation 2026-09-30 14:50:13 +02:00
7b5696eda4 feat(communication): federate tenant collaboration with signed delivery 2026-09-30 14:48:05 +02:00
ea641bb4d0 feat(communication): add project subrooms and isolated guest access 2026-09-30 14:23:03 +02:00
21fe4723e3 fix(communication): enforce room and project membership boundaries 2026-09-30 13:59:29 +02:00
052a3a8446 feat(documents): file scanner inbox documents with folder and type
All checks were successful
Build and Release FEDEO / verify (push) Successful in 1m0s
Build and Release FEDEO / build-and-release (push) Successful in 5m56s
2026-09-29 16:48:15 +02:00
2192fa5bb4 feat(documents): add Epson scanner inbox and document shelf 2026-09-29 12:42:05 +02:00
552a90e9e1 fix(storage): preserve preexisting Matrix health failures during restart 2026-09-28 20:47:38 +02:00
2b947c5e8f feat(updater): support updates after verified SeaweedFS migration 2026-09-28 15:47:06 +02:00
790f20b499 fix(storage): preserve explicit S3 MIME types in SeaweedFS 2026-09-28 14:34:30 +02:00
a3f4a7c004 fix(storage): verify migration of exports up to one GiB 2026-09-28 14:08:59 +02:00
e9b2e3e229 fix(storage): preserve retired Matrix containers during migration 2026-09-28 14:00:27 +02:00
ec5e240ef1 fix(banking): default bank allocations to no VAT 2026-09-28 07:21:45 +02:00
46ee819029 feat(storage): add verified offline MinIO migration pilot 2026-09-27 17:22:13 +02:00
0005bfc4cf docs(communication): define isolated project subrooms for guests 2026-09-26 13:29:25 +02:00
6a5de2a372 docs(communication): design chat federation and project invitations 2026-09-26 13:25:27 +02:00
df48c97677 fix(projects): load linked events in project details 2026-09-26 13:18:11 +02:00
b2c8f8b4e5 docs(storage): design MinIO replacement and migration 2026-09-25 19:55:10 +02:00
96a7acff33 Merge pull request 'feat(selfhost): show sanitized update logs in admin UI' (#231) from dev into main
All checks were successful
Build and Release FEDEO / verify (push) Successful in 47s
Build and Release FEDEO / build-and-release (push) Successful in 6m7s
Reviewed-on: #231
2026-09-25 17:22:30 +00:00
29155f916a feat(selfhost): show sanitized update logs in admin UI
All checks were successful
Build and Release FEDEO / verify (push) Successful in 48s
Build and Release FEDEO / build-and-release (push) Successful in 5m45s
2026-09-25 18:42:26 +02:00
65588686c7 Merge pull request 'fix(documents): normalize units when selecting and loading rows' (#230) from dev into main
All checks were successful
Build and Release FEDEO / verify (push) Successful in 48s
Build and Release FEDEO / build-and-release (push) Successful in 6m3s
Reviewed-on: #230
2026-09-25 09:54:08 +00:00
8f06d06037 fix(documents): normalize units when selecting and loading rows
All checks were successful
Build and Release FEDEO / verify (push) Successful in 49s
Build and Release FEDEO / build-and-release (push) Successful in 5m50s
2026-09-25 11:42:17 +02:00
fcf9cc3fc9 Merge pull request 'dev' (#229) from dev into main
All checks were successful
Build and Release FEDEO / verify (push) Successful in 49s
Build and Release FEDEO / build-and-release (push) Successful in 6m6s
Reviewed-on: #229
2026-09-25 09:24:39 +00:00
eaa5627062 fix(documents): initialize new documents as drafts
All checks were successful
Build and Release FEDEO / verify (push) Successful in 52s
Build and Release FEDEO / build-and-release (push) Successful in 5m57s
2026-09-25 11:14:09 +02:00
9fe5a9b1da fix(selfhost): reuse locally cached digest images during updates 2026-09-25 10:10:30 +02:00
a65bd72d74 feat(scan): whiten receipt backgrounds and embed OCR in PDFs 2026-09-24 17:41:30 +02:00
b9cfdbe29e fix(scan): allow slower SANE network discovery 2026-09-24 17:09:35 +02:00
dde46f10e1 fix(scan): generate valid systemd working directory 2026-09-24 17:06:52 +02:00
20091143d2 Merge pull request 'dev' (#228) from dev into main
All checks were successful
Build and Release FEDEO / verify (push) Successful in 45s
Build and Release FEDEO / build-and-release (push) Successful in 6m5s
Reviewed-on: #228
2026-09-23 17:20:58 +00:00
8e1505023b feat(selfhost): start full updates from administration
All checks were successful
Build and Release FEDEO / verify (push) Successful in 45s
Build and Release FEDEO / build-and-release (push) Successful in 5m49s
2026-09-23 18:49:10 +02:00
60553bbba8 fix(auth): defer dashboard loading until tenant selection 2026-09-23 18:21:40 +02:00
96295ee4f0 fix(scan): restore missing scanner database migrations 2026-09-23 18:21:37 +02:00
f708d0a2b2 Merge pull request 'dev' (#227) from dev into main
All checks were successful
Build and Release FEDEO / verify (push) Successful in 44s
Build and Release FEDEO / build-and-release (push) Successful in 6m7s
Reviewed-on: #227
2026-09-23 16:15:44 +00:00
7164989da9 feat(selfhost): add persistent host update service
All checks were successful
Build and Release FEDEO / verify (push) Successful in 47s
Build and Release FEDEO / build-and-release (push) Successful in 5m53s
2026-09-23 18:09:04 +02:00
cbec5b058d feat(banking): add cost centres and VAT to account allocations 2026-09-23 18:08:09 +02:00
847a616285 fix(selfhost): retire deprecated Matrix services during updates 2026-09-23 17:43:12 +02:00
fdf1d42a3d fix(selfhost): explain unsupported update services 2026-09-23 17:36:30 +02:00
7e9f4409f6 Merge pull request 'dev' (#226) from dev into main
All checks were successful
Build and Release FEDEO / verify (push) Successful in 33s
Build and Release FEDEO / build-and-release (push) Successful in 6m10s
Reviewed-on: #226
2026-09-23 14:57:40 +00:00
0ff74cdcdf feat(selfhost): add verified release updates with backups and recovery state
Some checks failed
Build and Release FEDEO / verify (push) Successful in 59s
Build and Release FEDEO / build-and-release (push) Failing after 4m59s
2026-09-23 16:52:00 +02:00
f51f2b13a1 fix(selfhost): pin MinIO images and add application health checks 2026-09-23 16:39:17 +02:00
2e63af1aa2 Merge pull request 'fix(release): stream large migration checksums from git' (#225) from flfeders/codex/release-migration-checksums into main
All checks were successful
Build and Release FEDEO / verify (push) Successful in 25s
Build and Release FEDEO / build-and-release (push) Successful in 5m59s
Reviewed-on: #225
2026-09-23 14:09:57 +00:00
74c0cf40b3 fix(release): stream large migration checksums from git
All checks were successful
Build and Release FEDEO / verify (push) Successful in 25s
Build and Release FEDEO / build-and-release (push) Successful in 5m50s
2026-09-23 15:37:19 +02:00
5ebd2d508c Merge pull request 'fix(release): exclude legacy main history from commit checks' (#224) from dev into main
Some checks failed
Build and Release FEDEO / verify (push) Successful in 23s
Build and Release FEDEO / build-and-release (push) Failing after 5m57s
Reviewed-on: #224
2026-09-23 13:03:36 +00:00
f6996c1d7b fix(release): exclude legacy main history from commit checks
All checks were successful
Build and Release FEDEO / verify (push) Successful in 25s
Build and Release FEDEO / build-and-release (push) Successful in 6m4s
2026-09-20 18:44:53 +02:00
9128fbb165 Merge pull request 'fix(ci): build dev images without repository write access' (#221) from dev into main
Some checks failed
Build and Release FEDEO / verify (push) Failing after 26s
Build and Release FEDEO / build-and-release (push) Has been skipped
Reviewed-on: #221
2026-09-20 16:25:38 +00:00
bb94e73229 fix(ci): build dev images without repository write access
All checks were successful
Build and Release FEDEO / verify (push) Successful in 25s
Build and Release FEDEO / build-and-release (push) Successful in 5m54s
2026-09-20 18:22:17 +02:00
8473221c13 Merge pull request '3.0.0' (#220) from dev into main
Some checks failed
Build and Release FEDEO / verify (push) Failing after 22s
Build and Release FEDEO / build-and-release (push) Has been skipped
Reviewed-on: #220
2026-09-20 16:10:46 +00:00
68c0a224e5 feat(scan): add guided Linux agent setup in administration
Some checks failed
Build and Release FEDEO / verify (push) Successful in 23s
Build and Release FEDEO / build-and-release (push) Failing after 29s
2026-09-17 18:56:30 +02:00
1329f164d8 chore(release): start FEDEO releases at 3.0.0 2026-09-17 18:46:51 +02:00
92859f3ccf feat(release): automate versioned releases on main 2026-09-17 18:41:53 +02:00
dd37622bb6 feat(scan): support iX1600 duplex scanning on Linux 2026-09-17 18:22:43 +02:00
cfef07b96d feat(mcp): manage master data and cost centre hierarchies 2026-09-14 13:29:25 +02:00
342ad9764e feat(mcp): paginate record lists and describe document inputs 2026-09-14 13:17:49 +02:00
58fc252110 fix: make project number editable 2026-09-14 13:09:57 +02:00
0c430e993e feat: configure planning board week end 2026-09-11 19:31:16 +02:00
a50ff256ee fix(accounting): validate serial invoice templates
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 43s
Build and Push Docker Images / build-frontend (push) Successful in 1m13s
Build and Push Docker Images / build-website (push) Successful in 24s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-09-09 14:38:24 +02:00
ebbd1e0cd0 feat(accounting): edit finalized document cost centres 2026-09-09 14:37:22 +02:00
2ec162c0e7 feat(mcp): support serial invoice workflows 2026-09-09 14:30:42 +02:00
d0bc8a5e0f fix(mcp): exclude archived records 2026-09-09 14:19:34 +02:00
a6f55b61e4 fix: Einheit in Artikelansicht laden
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 45s
Build and Push Docker Images / build-frontend (push) Successful in 22s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-09-09 14:00:34 +02:00
c383a291e1 Kundeninventar-Nummern kollisionsfrei vergeben
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 45s
Build and Push Docker Images / build-frontend (push) Successful in 21s
Build and Push Docker Images / build-website (push) Successful in 21s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 21s
2026-09-09 13:34:14 +02:00
0eadf42973 fix: Nummernkreise beim Öffnen aktualisieren
All checks were successful
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-docs (push) Successful in 21s
Build and Push Docker Images / build-backend (push) Successful in 23s
Build and Push Docker Images / build-frontend (push) Successful in 1m12s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
2026-09-09 13:10:50 +02:00
616bb5d7f3 fix: send employee test push via mobile service
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 43s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-admin (push) Successful in 23s
Build and Push Docker Images / build-frontend (push) Successful in 1m12s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-09-09 13:08:17 +02:00
6297480b89 Heroicons-Picker für Projektphasen ergänzen 2026-09-09 13:07:22 +02:00
48199b0ed7 fix: Lieferantenfenster direkt steuerbar machen
Some checks failed
Build and Push Docker Images / build-backend (push) Successful in 46s
Build and Push Docker Images / build-frontend (push) Successful in 1m12s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Has been cancelled
Build and Push Docker Images / build-central-services-admin (push) Has been cancelled
2026-09-09 13:04:28 +02:00
bb18a974dd fix: IBANs im Logbuch maskieren 2026-09-09 13:04:13 +02:00
4e05906556 Projekttyp-Verwaltung reparieren
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 46s
Build and Push Docker Images / build-frontend (push) Successful in 1m12s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 21s
2026-09-09 12:56:32 +02:00
df2308d407 fix: Schließen im Lieferantenfenster ermöglichen 2026-09-09 12:55:34 +02:00
5b6579423b feat: add employee push test button 2026-09-09 12:55:26 +02:00
b3dd46195d Merge remote-tracking branch 'origin/dev' into dev
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 26s
Build and Push Docker Images / build-frontend (push) Successful in 1m17s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-09-09 12:47:50 +02:00
54294ce7e9 fix: make planning board week start configurable 2026-09-09 12:46:08 +02:00
5141a1f3ac feat: Lieferantenanlage verschiebbar machen 2026-09-09 12:43:39 +02:00
718ecefd46 KI-AGENT: Scrollen in Dashboard-Seiten wiederherstellen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 45s
Build and Push Docker Images / build-frontend (push) Successful in 3m18s
Build and Push Docker Images / build-website (push) Successful in 36s
Build and Push Docker Images / build-central-services-api (push) Successful in 23s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 1m21s
2026-09-08 22:53:42 +02:00
e90cf819e7 KI-AGENT: iOS-Buildnummer für TestFlight auf 13 erhöhen 2026-09-08 22:50:46 +02:00
15e21a97e2 KI-AGENT: Terminpicker und Dokumentaufruf verbessert 2026-09-08 22:49:17 +02:00
358e40d749 KI-AGENT: Matrix durch nativen FEDEO-Chat ersetzen 2026-09-08 22:42:40 +02:00
47bd8e80e4 KI-AGENT: iOS-Buildnummer für TestFlight auf 12 erhöhen 2026-09-08 22:17:52 +02:00
92c354c1b9 KI-AGENT: Mobile Termine und Kalender ergänzen 2026-09-08 22:05:18 +02:00
5e1631e2d3 KI-AGENT: Mobile Kundenerfassung und Logbücher erweitern 2026-09-08 21:50:31 +02:00
1c39b69513 perf(email): update message actions optimistically
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 46s
Build and Push Docker Images / build-frontend (push) Successful in 1m15s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 1m21s
2026-09-08 10:18:00 +02:00
a60570e0eb fix(email): support legacy AI gateway models 2026-09-08 10:07:13 +02:00
41e4cad929 feat(email): add selection and bulk message actions
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 23s
Build and Push Docker Images / build-frontend (push) Successful in 1m15s
Build and Push Docker Images / build-website (push) Successful in 25s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 21s
2026-09-08 09:56:38 +02:00
1890d1d97d feat(email): allow dismissing entity suggestions
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 45s
Build and Push Docker Images / build-frontend (push) Successful in 1m16s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 1m18s
2026-09-08 09:54:56 +02:00
a09f770a63 fix(email): ignore recipient headers in entity suggestions 2026-09-08 09:51:47 +02:00
2462418548 Use Terra and Luna for task-specific AI processing
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 46s
Build and Push Docker Images / build-frontend (push) Successful in 22s
Build and Push Docker Images / build-website (push) Successful in 21s
Build and Push Docker Images / build-central-services-api (push) Successful in 29s
Build and Push Docker Images / build-central-services-admin (push) Successful in 48s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-09-08 09:46:37 +02:00
a1e0ec6ac5 feat(email): suggest entity links with AI when opening messages
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 48s
Build and Push Docker Images / build-frontend (push) Successful in 1m15s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 20s
Build and Push Docker Images / build-docs (push) Successful in 1m17s
2026-09-08 09:42:17 +02:00
ed2885084e KI-AGENT: Ausgabenbetrag im Betriebsergebnis abziehen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 23s
Build and Push Docker Images / build-frontend (push) Successful in 1m12s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 21s
2026-09-07 21:14:57 +02:00
252cbd496d KI-AGENT: BWA-Ausgaben nach Kontosaldo berechnen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 23s
Build and Push Docker Images / build-frontend (push) Successful in 1m11s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 1m20s
2026-09-07 21:04:31 +02:00
23d2dc0ca8 KI-AGENT: Niederlassungslager für Verkaufsbelege festlegen 2026-09-07 20:59:56 +02:00
ca4cf119c0 KI-AGENT: Lagerkonzept nach Fachentscheidungen konkretisieren 2026-09-07 20:59:10 +02:00
b89fdedeae KI-AGENT: Positive Kontobuchungen mit BWA-Ausgaben verrechnen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 21s
Build and Push Docker Images / build-frontend (push) Successful in 1m10s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 1m20s
2026-09-07 20:50:24 +02:00
e4fcd79c8e KI-AGENT: Lagersystem fachlich und technisch konzipieren 2026-09-07 20:44:04 +02:00
2ebd856df0 KI-AGENT: Mail-Editor übersichtlicher gestalten
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 21s
Build and Push Docker Images / build-frontend (push) Successful in 1m11s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 21s
2026-09-07 20:40:42 +02:00
60327fe928 KI-AGENT: Gegenkonten in der BWA vollständig saldieren
Some checks failed
Build and Push Docker Images / build-backend (push) Successful in 21s
Build and Push Docker Images / build-website (push) Has been cancelled
Build and Push Docker Images / build-central-services-api (push) Has been cancelled
Build and Push Docker Images / build-central-services-admin (push) Has been cancelled
Build and Push Docker Images / build-docs (push) Has been cancelled
Build and Push Docker Images / build-frontend (push) Has been cancelled
2026-09-07 20:38:10 +02:00
8d8b07ce0d KI-AGENT: Empfängerauswahl beim Mailversand erweitern 2026-09-07 20:31:20 +02:00
36969e272d KI-AGENT: Positive Geldtransitbuchungen in der BWA berücksichtigen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 22s
Build and Push Docker Images / build-frontend (push) Successful in 1m11s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-09-07 20:14:37 +02:00
dd063fd648 KI-AGENT: Dateivorschauen authentifiziert laden 2026-09-07 20:10:25 +02:00
2c7cd17e2b KI-AGENT: E-Mails per Drag-and-drop verschiebbar machen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 22s
Build and Push Docker Images / build-frontend (push) Successful in 1m12s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 21s
2026-09-07 19:59:44 +02:00
298f601564 KI-AGENT: Datei-Anzeige über korrekte Backend-URL laden 2026-09-07 19:57:55 +02:00
384a0a53ef KI-AGENT: Mailkonten deaktivierbar machen und Synczeit anzeigen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 44s
Build and Push Docker Images / build-frontend (push) Successful in 1m15s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-09-07 19:47:04 +02:00
5c481b105f KI-AGENT: Projekte in der Plantafel nach Zeitraum filtern 2026-09-07 19:47:02 +02:00
914b322805 KI-AGENT: Projekttermine in der Plantafel darstellen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 44s
Build and Push Docker Images / build-frontend (push) Successful in 1m16s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-09-07 19:32:28 +02:00
2f306ca8a2 KI-AGENT: Defekte Mailkonto-Verschlüsselung abfangen 2026-09-07 19:31:53 +02:00
49b4c10e10 KI-AGENT: Benutzerdarstellung in Terminbearbeitung korrigieren
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 49s
Build and Push Docker Images / build-frontend (push) Successful in 1m22s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-09-07 19:02:58 +02:00
f3384cfc74 KI-AGENT: Mailantworten und Entitätsverknüpfungen ergänzen 2026-09-07 19:00:08 +02:00
4e4466ff11 KI-AGENT: Termin- und Aufgabenaktionen in Phasen repariert 2026-09-06 21:35:35 +02:00
b5419bb5ea KI-AGENT: Passwort-Reset im Admin-Dashboard ergänzen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 48s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 21s
Build and Push Docker Images / build-frontend (push) Successful in 1m24s
Build and Push Docker Images / build-website (push) Successful in 23s
2026-09-04 08:00:46 +02:00
7c58b9021a Merge remote-tracking branch 'origin/dev' into dev
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 50s
Build and Push Docker Images / build-frontend (push) Successful in 25s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 23s
2026-09-04 07:48:52 +02:00
62eef04a6b KI-AGENT: Password-Reset gegen hängenden Mailversand absichern 2026-09-04 07:47:43 +02:00
root
2ad4dada92 Wiki-Bearbeitung im MCP ergänzen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 46s
Build and Push Docker Images / build-frontend (push) Successful in 23s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 23s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
2026-09-02 09:58:42 +00:00
root
21fb8c6649 Zentralen BIC-Abgleich robust machen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 44s
Build and Push Docker Images / build-frontend (push) Successful in 22s
Build and Push Docker Images / build-website (push) Successful in 21s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 23s
Build and Push Docker Images / build-docs (push) Successful in 21s
2026-09-01 13:17:37 +00:00
root
0bd862af55 Banking-OAuth-Redirect ohne Backend-Pfad erzeugen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 45s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-frontend (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-09-01 13:13:28 +00:00
root
2428230d94 Bankkonto-Aktualisierung über zentralen Dienst reparieren
All checks were successful
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
Build and Push Docker Images / build-backend (push) Successful in 44s
Build and Push Docker Images / build-frontend (push) Successful in 1m13s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
2026-09-01 12:24:34 +00:00
root
98a8d1d061 Textvorlagen-Modal Layout korrigieren
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 23s
Build and Push Docker Images / build-frontend (push) Successful in 1m15s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 23s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-09-01 06:42:43 +00:00
root
92686ead9a Bankkonto-Inhaber beim GoCardless-Sync aktualisieren
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 44s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-frontend (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-09-01 06:27:27 +00:00
root
95ca7a4aaf Textvorlagen-Modal scrollbar machen
All checks were successful
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
Build and Push Docker Images / build-backend (push) Successful in 23s
Build and Push Docker Images / build-frontend (push) Successful in 1m15s
2026-09-01 06:20:11 +00:00
root
f26743154a Tenant-Importe ohne ZIP-Buffering verarbeiten
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 44s
Build and Push Docker Images / build-frontend (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-website (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-08-31 20:20:02 +00:00
root
b1785a35a9 S3-Import mit bekannter Dateigröße hochladen
All checks were successful
Build and Push Docker Images / build-frontend (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-backend (push) Successful in 43s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 21s
2026-08-31 20:14:18 +00:00
root
405cc95b41 Tenant-Importe per Stream in den Object Storage laden
All checks were successful
Build and Push Docker Images / build-frontend (push) Successful in 21s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 21s
Build and Push Docker Images / build-backend (push) Successful in 43s
Build and Push Docker Images / build-website (push) Successful in 21s
2026-08-31 20:05:06 +00:00
a298712973 Merge remote-tracking branch 'origin/dev' into dev 2026-08-31 21:44:33 +02:00
root
a84bd0c445 Exportjob-Insert ohne neue Importspalten ausführen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 39s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-frontend (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-08-31 19:44:01 +00:00
12130395e3 Merge remote-tracking branch 'origin/dev' into dev 2026-08-31 21:40:50 +02:00
root
bcc72974b5 Exportjobs mit altem Tenant-Schema kompatibel machen
All checks were successful
Build and Push Docker Images / build-frontend (push) Successful in 22s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-backend (push) Successful in 44s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-08-31 19:38:25 +00:00
1ae76380a9 Merge remote-tracking branch 'origin/dev' into dev 2026-08-31 21:37:21 +02:00
root
f1ca725d89 Vorlagen beim Erstellen als Dokument laden
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 22s
Build and Push Docker Images / build-frontend (push) Successful in 1m12s
Build and Push Docker Images / build-website (push) Successful in 24s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 21s
2026-08-31 19:19:01 +00:00
root
0250cc0dd7 Pluszeichen aus Dokumentbuttons entfernen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 22s
Build and Push Docker Images / build-frontend (push) Successful in 1m15s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 21s
2026-08-31 19:07:11 +00:00
root
e86e66a6e4 Drizzle-Migration für Dokumentenvorlagen registrieren
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 43s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-frontend (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-08-31 18:59:23 +00:00
root
d90499a101 Dokumentenvorlagen im Ausgangsbeleg-Editor ergänzen
All checks were successful
Build and Push Docker Images / build-frontend (push) Successful in 1m22s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-backend (push) Successful in 43s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 21s
2026-08-31 18:49:40 +00:00
root
6afc799f69 MCP-Projektphasen aktualisierbar machen
All checks were successful
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
Build and Push Docker Images / build-backend (push) Successful in 45s
Build and Push Docker Images / build-frontend (push) Successful in 22s
2026-08-31 11:08:53 +00:00
root
02ab26771d MCP-Bankzuweisungen ergänzen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 50s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 21s
Build and Push Docker Images / build-frontend (push) Successful in 22s
2026-08-31 10:58:33 +00:00
40bd1769ee KI-AGENT: Upload-Timeout für Tenant-Import erhöhen 2026-08-27 08:51:01 +02:00
6b5d4f7f36 KI-AGENT: Statusanzeige für Tenant-Import ergänzen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 45s
Build and Push Docker Images / build-frontend (push) Successful in 1m21s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 21s
2026-08-27 08:50:17 +02:00
afb9adb444 KI-AGENT: Gmail-Download mit Debugausgaben erweitern
All checks were successful
Build and Push Docker Images / build-frontend (push) Successful in 24s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 1m23s
Build and Push Docker Images / build-backend (push) Successful in 29s
2026-08-27 07:44:45 +02:00
2dd333db1d KI-AGENT: Gmail-Postfachnamen korrekt quotieren 2026-08-27 07:42:10 +02:00
67e4e05f01 KI-AGENT: Tab und Pagination der Ausgangsbelege im Profil speichern
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 23s
Build and Push Docker Images / build-frontend (push) Successful in 1m13s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-08-17 19:51:37 +02:00
d0755020ad Ausgangsbeleg-Tabs schneller rendern
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 43s
Build and Push Docker Images / build-frontend (push) Successful in 1m26s
Build and Push Docker Images / build-central-services-admin (push) Successful in 31s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-08-17 17:59:51 +02:00
391375b3a7 Prevent duplicate invoice number reservations 2026-08-17 17:47:07 +02:00
060fde7bda Ausgangsbelegliste schlank laden
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 50s
Build and Push Docker Images / build-frontend (push) Successful in 1m23s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 22s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-docs (push) Successful in 22s
2026-08-17 17:43:09 +02:00
a71ea577b2 DATEV-Automatikkonten mit Bruttobeträgen exportieren
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 1m3s
Build and Push Docker Images / build-frontend (push) Successful in 35s
Build and Push Docker Images / build-website (push) Successful in 35s
Build and Push Docker Images / build-central-services-api (push) Successful in 34s
Build and Push Docker Images / build-docs (push) Successful in 34s
Build and Push Docker Images / build-central-services-admin (push) Successful in 35s
2026-08-11 13:41:01 +02:00
2917df6fa2 Merge remote-tracking branch 'origin/dev' into dev
All checks were successful
Build and Push Docker Images / build-central-services-admin (push) Successful in 35s
Build and Push Docker Images / build-docs (push) Successful in 34s
Build and Push Docker Images / build-backend (push) Successful in 1m0s
Build and Push Docker Images / build-frontend (push) Successful in 2m0s
Build and Push Docker Images / build-website (push) Successful in 37s
Build and Push Docker Images / build-central-services-api (push) Successful in 35s
2026-08-10 15:22:52 +02:00
5181ecc9f3 Fix hanging document mailbox imports 2026-08-10 15:16:42 +02:00
0bd2c01591 KI-AGENT: Exportdateien über API-Client herunterladen
All checks were successful
Build and Push Docker Images / build-website (push) Successful in 36s
Build and Push Docker Images / build-central-services-api (push) Successful in 35s
Build and Push Docker Images / build-central-services-admin (push) Successful in 35s
Build and Push Docker Images / build-backend (push) Successful in 35s
Build and Push Docker Images / build-frontend (push) Successful in 1m54s
Build and Push Docker Images / build-docs (push) Successful in 34s
2026-08-09 19:33:14 +02:00
3ed26225bb Merge remote-tracking branch 'origin/dev' into dev
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 59s
Build and Push Docker Images / build-frontend (push) Successful in 35s
Build and Push Docker Images / build-website (push) Successful in 34s
Build and Push Docker Images / build-central-services-admin (push) Successful in 34s
Build and Push Docker Images / build-central-services-api (push) Successful in 35s
Build and Push Docker Images / build-docs (push) Successful in 34s
2026-08-09 19:23:43 +02:00
86e5d49795 KI-AGENT: Interne MinIO-Links durch Backend-Downloads ersetzen 2026-08-09 19:20:19 +02:00
ee39ee59cc KI-AGENT: Ungültige Siri-Shortcut-Parameter korrigieren 2026-08-09 19:13:12 +02:00
49cbc9314e Handle files without stored paths
All checks were successful
Build and Push Docker Images / build-frontend (push) Successful in 1m54s
Build and Push Docker Images / build-website (push) Successful in 37s
Build and Push Docker Images / build-backend (push) Successful in 36s
Build and Push Docker Images / build-central-services-api (push) Successful in 35s
Build and Push Docker Images / build-central-services-admin (push) Successful in 34s
Build and Push Docker Images / build-docs (push) Successful in 34s
2026-08-09 18:15:37 +02:00
e5fab70056 Gebuchte Eingangsbelege bearbeitbar machen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 35s
Build and Push Docker Images / build-central-services-api (push) Successful in 35s
Build and Push Docker Images / build-docs (push) Successful in 33s
Build and Push Docker Images / build-frontend (push) Successful in 1m54s
Build and Push Docker Images / build-website (push) Successful in 35s
Build and Push Docker Images / build-central-services-admin (push) Successful in 34s
2026-08-09 17:47:20 +02:00
e7fe98da56 Eingangsbelege ohne Bankzuweisung archivieren 2026-08-09 17:42:44 +02:00
e12ec4557d Reduce duplicate dashboard data loading 2026-08-09 17:39:41 +02:00
17717e8a1b Speed up initial file listing 2026-08-09 17:38:17 +02:00
7d3e9a383f fix: use corrected invoice total for bank allocation
All checks were successful
Build and Push Docker Images / build-frontend (push) Successful in 37s
Build and Push Docker Images / build-central-services-api (push) Successful in 35s
Build and Push Docker Images / build-central-services-admin (push) Successful in 35s
Build and Push Docker Images / build-backend (push) Successful in 58s
Build and Push Docker Images / build-website (push) Successful in 34s
Build and Push Docker Images / build-docs (push) Successful in 36s
2026-08-09 17:14:53 +02:00
7ad55aaa0b Include manual tax accounts in VAT evaluation
All checks were successful
Build and Push Docker Images / build-central-services-api (push) Successful in 35s
Build and Push Docker Images / build-central-services-admin (push) Successful in 35s
Build and Push Docker Images / build-backend (push) Successful in 57s
Build and Push Docker Images / build-frontend (push) Successful in 1m58s
Build and Push Docker Images / build-website (push) Successful in 36s
Build and Push Docker Images / build-docs (push) Successful in 34s
2026-08-09 16:38:43 +02:00
8301d8777e feat: correct total tax on incoming invoices 2026-08-09 16:36:29 +02:00
94008e8072 Notizen in Bankauflistung kennzeichnen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 57s
Build and Push Docker Images / build-frontend (push) Successful in 1m56s
Build and Push Docker Images / build-website (push) Successful in 35s
Build and Push Docker Images / build-central-services-api (push) Successful in 33s
Build and Push Docker Images / build-central-services-admin (push) Successful in 33s
Build and Push Docker Images / build-docs (push) Successful in 33s
2026-08-09 16:25:21 +02:00
53463675ff Add requested SKR03 accounts 2026-08-09 14:31:12 +02:00
6473adca6c feat: flag adjusted tax in DATEV export
All checks were successful
Build and Push Docker Images / build-central-services-api (push) Successful in 35s
Build and Push Docker Images / build-docs (push) Successful in 34s
Build and Push Docker Images / build-central-services-admin (push) Successful in 34s
Build and Push Docker Images / build-backend (push) Successful in 59s
Build and Push Docker Images / build-website (push) Successful in 37s
Build and Push Docker Images / build-frontend (push) Successful in 1m58s
2026-08-09 14:20:39 +02:00
ae4ff9aad0 feat: allow manual input tax adjustments 2026-08-09 14:17:31 +02:00
09431a87c7 Fix document import account form submission
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 38s
Build and Push Docker Images / build-frontend (push) Successful in 1m58s
Build and Push Docker Images / build-central-services-api (push) Successful in 35s
Build and Push Docker Images / build-docs (push) Successful in 34s
Build and Push Docker Images / build-website (push) Successful in 37s
Build and Push Docker Images / build-central-services-admin (push) Successful in 35s
2026-08-09 13:48:45 +02:00
d0b76e0bab KI-AGENT: iOS-Buildnummer für Siri-Korrektur auf 11 erhöhen 2026-08-08 23:26:32 +02:00
7d92726cf8 KI-AGENT: Siri-Erkennung für Todo-Befehle verbessern 2026-08-08 23:22:13 +02:00
e5246d45c8 KI-AGENT: iOS-Buildnummer für TestFlight auf 10 erhöhen 2026-08-08 22:59:59 +02:00
ecbfdaa0cb KI-AGENT: Siri-Kurzbefehle für FEDEO-Todos ergänzen 2026-08-08 22:59:15 +02:00
5dae5b6aa5 KI-AGENT: Multi-File-Upload für iOS Share Target absichern 2026-08-08 22:41:58 +02:00
ca91de2284 KI-AGENT: Share-Upload an FEDEO-Design und Listenfilter angleichen 2026-08-08 22:36:09 +02:00
ec4469e21f KI-AGENT: iOS-Buildnummer für TestFlight auf 9 erhöhen 2026-08-08 21:52:52 +02:00
9a09c3f722 KI-AGENT: iOS Share Target mit Upload-Strecke ergänzen 2026-08-08 21:50:52 +02:00
21fdbb1cf8 KI-AGENT: iOS-Buildnummer für TestFlight auf 8 erhöhen 2026-08-08 21:08:52 +02:00
3d829c3bc0 Banknotizen automatisch speichern
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 37s
Build and Push Docker Images / build-website (push) Successful in 36s
Build and Push Docker Images / build-frontend (push) Successful in 2m8s
Build and Push Docker Images / build-central-services-api (push) Successful in 36s
Build and Push Docker Images / build-docs (push) Successful in 35s
Build and Push Docker Images / build-central-services-admin (push) Successful in 35s
2026-08-08 09:18:17 +02:00
93d2769f23 KI-AGENT: Migration für Dokumentenimporte aktivieren
All checks were successful
Build and Push Docker Images / build-central-services-api (push) Successful in 34s
Build and Push Docker Images / build-docs (push) Successful in 34s
Build and Push Docker Images / build-backend (push) Successful in 58s
Build and Push Docker Images / build-frontend (push) Successful in 1m59s
Build and Push Docker Images / build-website (push) Successful in 34s
Build and Push Docker Images / build-central-services-admin (push) Successful in 34s
2026-08-07 21:23:52 +02:00
9822d90bdd KI-AGENT: Verbinden-Button für Bankkonten repariert
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 1m2s
Build and Push Docker Images / build-website (push) Successful in 37s
Build and Push Docker Images / build-frontend (push) Successful in 1m58s
Build and Push Docker Images / build-central-services-api (push) Successful in 36s
Build and Push Docker Images / build-central-services-admin (push) Successful in 35s
Build and Push Docker Images / build-docs (push) Successful in 35s
2026-08-07 21:13:06 +02:00
519a90bdc1 KI-AGENT: Mandantenbezogenen IMAP-Dokumentenimport umsetzen 2026-08-07 21:07:05 +02:00
75d7bfab38 KI-AGENT: Notizen für Bankbuchungen ergänzt 2026-08-07 19:21:38 +02:00
9421c3221c Dashboard-Ladezeit durch geteilte Datenabfragen optimiert 2026-08-07 19:07:20 +02:00
d2e0b4ca0f Load bank booking list before suggestions
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 35s
Build and Push Docker Images / build-frontend (push) Successful in 1m56s
Build and Push Docker Images / build-website (push) Successful in 37s
Build and Push Docker Images / build-central-services-api (push) Successful in 33s
Build and Push Docker Images / build-central-services-admin (push) Successful in 34s
Build and Push Docker Images / build-docs (push) Successful in 33s
2026-08-06 15:45:11 +02:00
7677fe5d9d Show bank bookings before supporting data loads 2026-08-06 15:41:09 +02:00
1caa3180af Seed global reference data from exports
All checks were successful
Build and Push Docker Images / build-frontend (push) Successful in 2m1s
Build and Push Docker Images / build-backend (push) Successful in 58s
Build and Push Docker Images / build-website (push) Successful in 35s
Build and Push Docker Images / build-central-services-api (push) Successful in 35s
Build and Push Docker Images / build-central-services-admin (push) Successful in 34s
Build and Push Docker Images / build-docs (push) Successful in 34s
2026-08-06 15:31:53 +02:00
cb37970074 Restrict tenant imports to new tenants 2026-08-06 15:19:11 +02:00
c66d04f0b5 Handle missing tables in tenant merge
All checks were successful
Build and Push Docker Images / build-central-services-api (push) Successful in 24s
Build and Push Docker Images / build-central-services-admin (push) Successful in 24s
Build and Push Docker Images / build-docs (push) Successful in 24s
Build and Push Docker Images / build-backend (push) Successful in 38s
Build and Push Docker Images / build-frontend (push) Successful in 1m42s
Build and Push Docker Images / build-website (push) Successful in 27s
2026-08-06 14:52:38 +02:00
5a05d2e9e8 Fix tenant merge review layout 2026-08-06 14:47:01 +02:00
ec4e3f39d6 Prevent tenant merge dry-run memory spikes
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 39s
Build and Push Docker Images / build-frontend (push) Successful in 24s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 24s
Build and Push Docker Images / build-central-services-admin (push) Successful in 24s
Build and Push Docker Images / build-docs (push) Successful in 24s
2026-08-06 14:39:58 +02:00
291f278d99 Add tenant merge review page
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 39s
Build and Push Docker Images / build-frontend (push) Successful in 1m43s
Build and Push Docker Images / build-central-services-api (push) Successful in 23s
Build and Push Docker Images / build-docs (push) Successful in 24s
Build and Push Docker Images / build-website (push) Successful in 26s
Build and Push Docker Images / build-central-services-admin (push) Successful in 24s
2026-08-06 12:35:31 +02:00
e2fdfe9c0a Execute reviewed tenant merges safely 2026-08-06 12:34:52 +02:00
a2c5ad5dd9 Create tenant merge review jobs 2026-08-06 12:27:27 +02:00
fd330b28c2 Connect tenant merge planner to exports 2026-08-06 12:26:00 +02:00
f691e3db33 Add tenant merge dry-run planner 2026-08-06 12:24:43 +02:00
13936db100 Move expense options into advanced booking
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 24s
Build and Push Docker Images / build-frontend (push) Successful in 1m45s
Build and Push Docker Images / build-website (push) Successful in 27s
Build and Push Docker Images / build-central-services-api (push) Successful in 24s
Build and Push Docker Images / build-central-services-admin (push) Successful in 24s
Build and Push Docker Images / build-docs (push) Successful in 23s
2026-08-06 11:51:17 +02:00
78d56738e8 Clarify bank allocation action 2026-08-06 11:45:21 +02:00
c8a7f4f396 Speed up bank allocation updates 2026-08-06 11:42:19 +02:00
f375d63655 Include global resources in tenant exports
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 39s
Build and Push Docker Images / build-frontend (push) Successful in 25s
Build and Push Docker Images / build-website (push) Successful in 24s
Build and Push Docker Images / build-central-services-api (push) Successful in 24s
Build and Push Docker Images / build-central-services-admin (push) Successful in 25s
Build and Push Docker Images / build-docs (push) Successful in 24s
2026-08-06 11:11:31 +02:00
52490ff734 Fix number ranges after tenant import
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 45s
Build and Push Docker Images / build-frontend (push) Successful in 25s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 23s
Build and Push Docker Images / build-central-services-admin (push) Successful in 24s
Build and Push Docker Images / build-docs (push) Successful in 24s
2026-08-06 11:00:48 +02:00
7b705c7f40 fix: cors fuer admin schreibzugriffe erlauben
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 16s
Build and Push Docker Images / build-website (push) Successful in 16s
Build and Push Docker Images / build-central-services-api (push) Successful in 24s
Build and Push Docker Images / build-central-services-admin (push) Successful in 41s
Build and Push Docker Images / build-docs (push) Successful in 16s
2026-08-05 14:17:23 +02:00
4e533a47c9 fix: bank sync fehler sichtbar machen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 26s
Build and Push Docker Images / build-frontend (push) Successful in 1m15s
Build and Push Docker Images / build-website (push) Successful in 19s
Build and Push Docker Images / build-central-services-api (push) Successful in 16s
Build and Push Docker Images / build-central-services-admin (push) Successful in 17s
Build and Push Docker Images / build-docs (push) Successful in 16s
2026-08-05 14:12:16 +02:00
8aee8e7882 fix: instanzdetail als eigene route rendern
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 17s
Build and Push Docker Images / build-website (push) Successful in 16s
Build and Push Docker Images / build-central-services-api (push) Successful in 23s
Build and Push Docker Images / build-central-services-admin (push) Successful in 40s
Build and Push Docker Images / build-docs (push) Successful in 16s
2026-08-05 13:51:32 +02:00
d18ba16f8a feat: central services heartbeat senden
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 26s
Build and Push Docker Images / build-frontend (push) Successful in 16s
Build and Push Docker Images / build-website (push) Successful in 16s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 41s
Build and Push Docker Images / build-docs (push) Successful in 16s
2026-08-05 13:49:22 +02:00
de36589822 fix: instanzdetail zuverlässig öffnen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 17s
Build and Push Docker Images / build-website (push) Successful in 16s
Build and Push Docker Images / build-central-services-api (push) Successful in 23s
Build and Push Docker Images / build-central-services-admin (push) Successful in 42s
Build and Push Docker Images / build-docs (push) Successful in 17s
2026-08-05 13:46:04 +02:00
b02466667a fix: api healthcheck ohne wget ausführen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 16s
Build and Push Docker Images / build-website (push) Successful in 17s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-central-services-admin (push) Successful in 41s
Build and Push Docker Images / build-docs (push) Successful in 16s
2026-08-05 12:21:58 +02:00
a49b05dba6 fix: traefik docker api kompatibilität
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 15s
Build and Push Docker Images / build-website (push) Successful in 16s
Build and Push Docker Images / build-central-services-api (push) Successful in 23s
Build and Push Docker Images / build-central-services-admin (push) Successful in 41s
Build and Push Docker Images / build-docs (push) Successful in 17s
2026-08-05 12:17:57 +02:00
28c5e8511f ci: central services images veröffentlichen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 33s
Build and Push Docker Images / build-frontend (push) Successful in 18s
Build and Push Docker Images / build-website (push) Successful in 16s
Build and Push Docker Images / build-central-services-api (push) Successful in 38s
Build and Push Docker Images / build-central-services-admin (push) Successful in 1m0s
Build and Push Docker Images / build-docs (push) Successful in 17s
2026-08-02 17:23:30 +02:00
3755b4136a feat: central services mit traefik deployen 2026-08-02 17:21:20 +02:00
8b8e0c97d3 feat: zentrale selfhost-dienste bereitstellen 2026-08-02 16:34:10 +02:00
d3ad53bcf0 Improve unsupported PDF character errors
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 30s
Build and Push Docker Images / build-frontend (push) Successful in 1m12s
Build and Push Docker Images / build-website (push) Successful in 18s
Build and Push Docker Images / build-docs (push) Successful in 17s
2026-07-24 10:25:10 +02:00
4ab4c24b1a Avoid unnecessary invoice QR page break 2026-07-22 20:51:13 +02:00
e7107f151a Reserve invoice QR code space 2026-07-22 20:46:52 +02:00
c222b793b0 Raise invoice payment QR code 2026-07-22 19:48:30 +02:00
5dcdc29a18 Place invoice payment QR code bottom right 2026-07-22 19:45:01 +02:00
fbea66b754 Use tenant business payment info for invoice QR codes 2026-07-22 19:40:01 +02:00
621243ba7b Merge remote-tracking branch 'origin/dev' into dev 2026-07-22 19:10:11 +02:00
dd2a9926dc Add payment QR code to invoice PDFs 2026-07-22 18:51:13 +02:00
3230fc6cf0 KI-AGENT: Spaltenbreiten eingeklappter Titelbereiche erhalten
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 2m12s
Build and Push Docker Images / build-frontend (push) Successful in 1m18s
Build and Push Docker Images / build-website (push) Successful in 19s
Build and Push Docker Images / build-docs (push) Successful in 17s
2026-07-21 21:48:19 +02:00
b8220685d7 KI-AGENT: Position des Titelbereich-Schalters stabilisieren 2026-07-21 21:45:58 +02:00
b7b8a2077a KI-AGENT: Einklappbare Titelbereiche im Dokumenteneditor ergänzen 2026-07-21 21:40:07 +02:00
5e7a1f9aee KI-AGENT: E-Rechnungen in der Belegvorbereitung verarbeiten 2026-07-21 20:20:34 +02:00
6c613857fa KI-AGENT: ZUGFeRD- und E-Rechnungserkennung ergänzen 2026-07-21 19:59:44 +02:00
430ab74522 Merge remote-tracking branch 'origin/dev' into dev 2026-07-21 19:55:51 +02:00
5585bd7012 KI-AGENT: Refresh-Token für Web-Sitzungen ergänzen 2026-07-20 22:12:09 +02:00
657a4f9e85 KI-AGENT: Persistente App-Sessions mit Refresh-Tokens ergänzen 2026-07-20 22:01:08 +02:00
769185cd82 Leeren individuellen Aufschlag normalisieren 2026-07-20 19:35:07 +02:00
37d08ee984 Prevent duplicate tenant memberships on import
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 37s
Build and Push Docker Images / build-frontend (push) Successful in 1m18s
Build and Push Docker Images / build-website (push) Successful in 17s
Build and Push Docker Images / build-docs (push) Successful in 16s
2026-07-20 19:06:01 +02:00
720c70845e Rechnungsbeträge deutsch formatieren 2026-07-20 10:17:00 +02:00
ae379b0f22 Aggregate nested document title sums 2026-07-15 13:21:31 +02:00
6a14b0c1ca Extend document title levels 2026-07-15 13:11:57 +02:00
d8273e794d Merge remote-tracking branch 'origin/dev' into dev
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 2m0s
Build and Push Docker Images / build-frontend (push) Successful in 1m13s
Build and Push Docker Images / build-website (push) Successful in 20s
Build and Push Docker Images / build-docs (push) Successful in 16s
2026-07-15 12:49:25 +02:00
1711f975bb KI-AGENT: Dropdown zum Einfügen von Dokumentpositionen ergänzt 2026-07-15 10:15:11 +02:00
4e3f1e0c15 Include letterhead files in tenant archive
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 27s
Build and Push Docker Images / build-frontend (push) Successful in 1m10s
Build and Push Docker Images / build-website (push) Successful in 17s
Build and Push Docker Images / build-docs (push) Successful in 16s
2026-07-14 17:33:05 +02:00
a9b063aa89 Add tenant import progress polling 2026-07-14 17:27:59 +02:00
473c92d2e4 docs: describe selfhost install and update flow
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 26s
Build and Push Docker Images / build-frontend (push) Successful in 16s
Build and Push Docker Images / build-website (push) Successful in 16s
Build and Push Docker Images / build-docs (push) Successful in 16s
2026-07-14 17:04:24 +02:00
3153a7a669 Allow terminating idle migration blockers 2026-07-14 16:58:01 +02:00
d0f5a72350 Diagnose tenant lock migration blockers 2026-07-14 16:50:27 +02:00
4c03a96cbe Add logging to tenant lock migration script 2026-07-14 16:48:37 +02:00
bf9e397e51 Add tenant lock migration repair script 2026-07-14 16:40:32 +02:00
31ef408b66 Merge remote-tracking branch 'origin/dev' into dev 2026-07-14 16:33:07 +02:00
a945aaffe3 Extend tenant maintenance lock for imports
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 27s
Build and Push Docker Images / build-frontend (push) Successful in 1m11s
Build and Push Docker Images / build-website (push) Successful in 18s
Build and Push Docker Images / build-docs (push) Successful in 16s
2026-07-14 11:40:48 +02:00
5f66f81ade Merge remote-tracking branch 'origin/dev' into dev 2026-07-13 21:22:36 +02:00
ee7d3d3afc Fix letterhead remapping in tenant import
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 33s
Build and Push Docker Images / build-frontend (push) Successful in 18s
Build and Push Docker Images / build-website (push) Successful in 17s
Build and Push Docker Images / build-docs (push) Successful in 17s
2026-07-13 18:14:27 +02:00
b3067e0e00 KI-AGENT: Erhöht iOS-Buildnummer nach Icon-Korrektur 2026-07-09 08:13:25 +02:00
e30722995e KI-AGENT: Ergänzt native Expo-Dateisystem-Abhängigkeit 2026-07-09 07:59:28 +02:00
bbef553e6b KI-AGENT: Erhöht iOS-Buildnummer für TestFlight 2026-07-09 07:57:48 +02:00
53632d25ac KI-AGENT: Aktualisiert Expo-Patch-Versionen 2026-07-09 07:46:23 +02:00
2eaa49bf05 KI-AGENT: Aktualisiert Mobile-App-Icons 2026-07-09 07:41:52 +02:00
14026181c2 KI-AGENT: Stabilisiert mobilen Session-Start 2026-07-09 07:34:44 +02:00
c54e9a51a5 Fix tenant archive S3 upload
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 26s
Build and Push Docker Images / build-frontend (push) Successful in 58s
Build and Push Docker Images / build-website (push) Successful in 13s
Build and Push Docker Images / build-docs (push) Successful in 12s
2026-07-05 12:41:23 +02:00
3c4a75a858 Wire tenant archive export in frontend 2026-07-05 12:31:59 +02:00
0a7b0448ad Add prepared tenant export archives 2026-07-05 12:25:39 +02:00
d67da7e02a KI-AGENT: Skript zum Löschen von Rechnungsbereichen ergänzen 2026-07-03 20:56:15 +02:00
3b3a879b02 KI-AGENT: Individuellen Aufschlag bei importierten Abschlagsrechnungen verhindern 2026-06-15 10:41:49 +02:00
365cec206d KI-AGENT: Selfhost-Netzwerke beim Setup bereinigen 2026-06-03 15:15:33 +02:00
033e74adda KI-AGENT: Matrix-Raumdaten nach Tenant-Import zurücksetzen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 19s
Build and Push Docker Images / build-frontend (push) Successful in 11s
Build and Push Docker Images / build-website (push) Successful in 11s
Build and Push Docker Images / build-docs (push) Successful in 10s
2026-06-03 15:06:33 +02:00
ccc66ebd0f KI-AGENT: Matrix-Daten beim Tenant-Import neu provisionieren 2026-06-03 10:43:40 +02:00
c660f62120 KI-AGENT: Veraltete Matrix-Raumreferenzen bereinigen 2026-06-03 10:40:00 +02:00
ad74825781 KI-AGENT: Matrix-Kommunikation im Selfhost-Bootstrap provisionieren
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 19s
Build and Push Docker Images / build-frontend (push) Successful in 10s
Build and Push Docker Images / build-website (push) Successful in 11s
Build and Push Docker Images / build-docs (push) Successful in 11s
2026-06-03 10:22:30 +02:00
f1e0f36cca KI-AGENT: Datenbank-URL im Selfhost-Setup absichern 2026-06-03 10:09:43 +02:00
526ad966c4 KI-AGENT: Selfhost-Setup nutzt passende Compose-Datei
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 11s
Build and Push Docker Images / build-frontend (push) Successful in 10s
Build and Push Docker Images / build-website (push) Successful in 11s
Build and Push Docker Images / build-docs (push) Successful in 11s
2026-06-03 10:02:34 +02:00
99501fb924 KI-AGENT: Uninstall für Selfhost-Setup ergänzen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 12s
Build and Push Docker Images / build-frontend (push) Successful in 11s
Build and Push Docker Images / build-docs (push) Successful in 11s
Build and Push Docker Images / build-website (push) Successful in 11s
2026-06-03 09:55:40 +02:00
2fdc89565c KI-AGENT: Encryption-Key im Selfhost-Setup als Hex erzeugen 2026-06-03 09:53:23 +02:00
427c0580c4 Kommunikationsdokumentation ergänzen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 21s
Build and Push Docker Images / build-frontend (push) Successful in 2m29s
Build and Push Docker Images / build-website (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 57s
Dokumentiert Matrix-Kommunikation, Telekom-Telefonie und den VPS-Asterisk-Entwicklungsbetrieb.
2026-06-03 09:27:20 +02:00
47a9af26fe Tenantdaten vollständig laden
Lädt den aktiven Tenant über die Tenant-Route nach und gibt calendarConfig in der Me-Antwort mit zurück.
2026-06-03 09:27:08 +02:00
42d2d7dc0e Website Docker Compose für Traefik ergänzt 2026-06-03 09:17:18 +02:00
6e0868582a Geräte-Agent als Container verpacken 2026-06-03 09:09:12 +02:00
7a6bb4552e OpenCV Abhängigkeiten für Agent besser verpacken 2026-06-03 09:03:26 +02:00
0ecdff4d7d OpenCV Pipeline für Scan Korrekturen ergänzen 2026-06-02 16:37:38 +02:00
0ea4efdc43 Scan aus der Dateienseite starten 2026-06-02 16:23:27 +02:00
c854b0bf30 Scanner Verwaltung für Geräte-Agenten ergänzen 2026-06-02 15:25:00 +02:00
a26ff30cd8 Geräte-Agent für lokale Scan-Aufträge anlegen 2026-06-02 12:59:04 +02:00
e9504e21e7 Token für Reload zusätzlich lokal sichern 2026-06-02 12:14:16 +02:00
822dcdcfb9 Serverseitigen Login-Redirect vermeiden 2026-06-02 12:06:42 +02:00
78f9bd3f7a Auth-Redirect vor Bootstrap verhindern 2026-06-02 12:03:34 +02:00
4aea8b94c3 Auth-Middleware aus Cookie initialisieren 2026-06-02 12:00:08 +02:00
79d620d9c1 Token-Cookie pfadunabhängig speichern 2026-06-02 11:54:18 +02:00
8d821a6802 Reload während Authentifizierung erlauben 2026-06-02 11:47:45 +02:00
363163f741 KI-AGENT: Datum bei Kassenbucheintrag erlauben 2026-06-01 16:26:57 +02:00
384ea95fe5 Instanzweite Scan-Agenten vorbereiten 2026-05-31 11:52:22 +02:00
2a5071b15a KI-AGENT: Kassenbucheintrag vereinfacht anlegen 2026-05-28 16:43:03 +02:00
f2055d59eb KI-AGENT: Kontenauswahl im Bankportal stabilisieren 2026-05-28 16:38:32 +02:00
b91c9d0fd8 KI-AGENT: Kassenbuch ins Bankportal integrieren 2026-05-28 16:35:50 +02:00
29a9e2b63b KI-AGENT: Gmail-Anhänge-Download-Skript hinzufügen 2026-05-26 21:20:51 +02:00
5264cf54ac Zeilen-Kostenstelle ins Positionsmenü verschieben 2026-05-26 16:30:06 +02:00
f002ad867a Login bei abgelaufener Sitzung korrigieren 2026-05-26 16:27:08 +02:00
cb09651d8d Ausgangsbelege um Kostenstellenzuordnung erweitern 2026-05-26 16:21:24 +02:00
b59599cb92 E-Mail Download direkt navigieren
KI-AGENT: Der Anhang-Download nutzt jetzt eine direkte Browser-Navigation zur Backend-Download-Route, damit der Browser den Attachment-Header sichtbar verarbeitet.
2026-05-23 21:06:46 +02:00
154d7060f8 E-Mail Anhänge ohne Fetch herunterladen
KI-AGENT: Der E-Mail Anhang-Download nutzt jetzt einen nativen Browser-Link statt Cross-Origin-Fetch und erlaubt dafür den bestehenden JWT gezielt als Download-Token.
2026-05-23 21:04:53 +02:00
a34bf43756 E-Mail Anhang-Download CORS absichern
KI-AGENT: OPTIONS-Preflights werden nicht mehr durch den Auth-Hook blockiert und der E-Mail Anhang-Download setzt CORS-Header auch für Fehlerantworten explizit.
2026-05-23 21:02:45 +02:00
2c96b9c5a5 E-Mail Anhänge gezielt per IMAP-Part laden
KI-AGENT: Der Anhang-Download lädt jetzt bevorzugt den passenden MIME-Part über die IMAP-BODYSTRUCTURE und bekommt ein Timeout, damit der Download nicht dauerhaft lädt.
2026-05-23 21:00:28 +02:00
d45cefbc20 E-Mail Anhang-Download über API-Client laden
KI-AGENT: Der Attachment-Download nutzt jetzt den zentralen API-Client mit apiBase, damit keine Frontend-HTML-Seite mehr als PDF gespeichert wird.
2026-05-23 20:54:29 +02:00
4fd2eb9c40 E-Mail PDF-Downloads als Binärdaten stabilisieren
KI-AGENT: Attachment-Downloads werden im Backend explizit als Buffer mit Content-Length ausgeliefert und im Frontend aus einem ArrayBuffer als Blob erzeugt, damit PDF-Anhänge unverändert gespeichert werden.
2026-05-23 20:52:22 +02:00
8697810127 E-Mail Anhang-Downloads stabilisieren
KI-AGENT: Lädt Anhänge nun authentifiziert als Blob herunter und macht die Backend-Zuordnung von Anhängen zur Originalmail robuster, inklusive Positions-Fallback.
2026-05-23 20:42:56 +02:00
358cd906ae E-Mail Aktionen und Anhang-Download ergänzen
KI-AGENT: Ergänzt IMAP-basierte Aktionen zum Verschieben, Archivieren und Löschen von E-Mails sowie den Download von Anhängen aus der Originalmail. Die E-Mail Oberfläche bietet dafür Zielordner-Auswahl, Aktionsbuttons und Anhang-Downloads.
2026-05-23 20:38:01 +02:00
be4a5caaec E-Mail Anzeige für Ordner erhalten
KI-AGENT: Behält den ausgewählten E-Mail Ordner beim Aktualisieren bei und synchronisiert leere Nicht-Posteingang-Ordner beim ersten Öffnen automatisch, damit deren Nachrichten angezeigt werden.
2026-05-23 20:28:42 +02:00
f2adc21fea E-Mail Ordner einklappbar machen
KI-AGENT: Ergänzt auf- und zuklappbare IMAP-Ordner in der E-Mail Übersicht. Elternordner bleiben initial sichtbar, ausgewählte Unterordner öffnen automatisch ihre übergeordneten Ordner.
2026-05-23 20:15:43 +02:00
7239ad92e4 E-Mail Lesestatus und Ordnerhierarchie synchronisieren
KI-AGENT: Synchronisiert Gelesen/Ungelesen mit IMAP, gleicht vorhandene Nachrichten-Flags beim Sync ab und zeigt verschachtelte IMAP-Ordner unter ihren Elternordnern an.
2026-05-23 20:13:35 +02:00
347319aee3 E-Mail Oberfläche im Outlook-Stil ergänzen
KI-AGENT: Ergänzt eine dreispaltige E-Mail Arbeitsansicht mit Konto- und Ordnerliste, Nachrichtenliste, Lesebereich, Suche, Aktualisierung und Composer-Verknüpfung. Die Navigation zeigt nun auf die neue E-Mail Übersicht.
2026-05-23 20:07:54 +02:00
21e2bc2755 E-Mail Cache und Konto-Synchronisation vorbereiten
KI-AGENT: Ergänzt Tabellen für lokalen E-Mail-Cache, IMAP-Sync-Service und Inbox-API. Überarbeitet außerdem die E-Mail-Konto-Seiten mit sicherer Passwortbehandlung und manuellem Sync.
2026-05-23 20:00:05 +02:00
c699d2ade8 KI-AGENT: Matrix Push Worker Rate Limit entschärfen 2026-05-22 21:35:33 +02:00
51e0ae95b1 KI-AGENT: Matrix Push Worker Diagnose ergänzen 2026-05-22 21:32:47 +02:00
45ca4f7327 KI-AGENT: Matrix Service User automatisch in Räume aufnehmen 2026-05-22 21:29:31 +02:00
38ccdd058b KI-AGENT: Fehlende Matrix Medienvorschauen nicht wiederholt laden 2026-05-22 21:24:17 +02:00
7f47821a7f KI-AGENT: Matrix Push Worker für ungelesene Nachrichten ergänzen 2026-05-22 21:21:08 +02:00
f150cfd740 KI-AGENT: Ungelesene Chat Badges in Mobile App anzeigen 2026-05-22 18:51:33 +02:00
00da371dfb KI-AGENT: Direktchat Push Empfänger korrigieren 2026-05-22 18:47:17 +02:00
c56fb6b571 KI-AGENT: Matrix Sync Push für eingehende Nachrichten ergänzen 2026-05-22 18:39:15 +02:00
0328a4586a KI-AGENT: Push Test im Admin Dashboard ergänzen 2026-05-22 18:32:15 +02:00
d73209a150 KI-AGENT: APNs Private Key im Push Server normalisieren 2026-05-22 18:28:52 +02:00
4bcc2152ab KI-AGENT: Mobile Build fünf für TestFlight vorbereiten 2026-05-22 18:23:46 +02:00
ab4055f2a5 KI-AGENT: Leere JSON Requests in der Mobile App korrigieren 2026-05-22 18:18:09 +02:00
d6582dd767 KI-AGENT: Mobile Build für TestFlight vorbereiten 2026-05-22 18:13:04 +02:00
3d5bec4ef8 KI-AGENT: Push-Server Env Datei fest laden 2026-05-22 18:01:35 +02:00
5963a9280c KI-AGENT: Seafile aus Standard-Stack entfernen 2026-05-22 17:54:25 +02:00
cacfce4d15 KI-AGENT: Mobile Push Registrierung anbinden 2026-05-22 17:34:52 +02:00
5400fd7ad5 KI-AGENT: Seafile Nebenpfade auf Hauptdomain routen 2026-05-22 17:30:24 +02:00
0d0dc33e84 KI-AGENT: Push-Server Migrationen stabilisieren 2026-05-22 17:22:01 +02:00
0e2e4a36be KI-AGENT: Seafile Subpfad Routing korrigieren 2026-05-22 17:21:28 +02:00
5403418c42 KI-AGENT: Frontend Route im Selfhost-Stack niedriger priorisieren 2026-05-22 17:16:24 +02:00
ab0f892bc1 KI-AGENT: Seafile Route vor Frontend priorisieren 2026-05-22 17:13:38 +02:00
69874742f8 KI-AGENT: Seafile unter Hauptdomain bereitstellen 2026-05-22 17:11:39 +02:00
736f7bba88 KI-AGENT: Nuxt UI Styles im Push Admin laden 2026-05-22 17:10:24 +02:00
ff4328f264 KI-AGENT: Matrix Element Config im Selfhost-Stack schreibbar machen 2026-05-22 17:07:45 +02:00
71f5763f7b KI-AGENT: Seafile Redis Secret URL-sicher erzeugen 2026-05-22 17:07:06 +02:00
5a4de421ce KI-AGENT: Zentralen Push-Server Stack ergänzen 2026-05-22 16:53:27 +02:00
19bab852de KI-AGENT: Seafile in Selfhost-Stack integrieren 2026-05-22 16:34:29 +02:00
8a2429827c KI-AGENT: Anrufbuttons und Telefoniejournal erweitern 2026-05-22 16:14:07 +02:00
3594dc69e8 KI-AGENT: Mobile App-Icons für Store vorbereiten 2026-05-22 16:13:26 +02:00
25e0c5389c Dokumentiere zentralen Push-Server
KI-AGENT: Entwirft den zentralen Push-Server für Selfhost-Instanzen, beschreibt API, Sicherheit, Datenschutz und Migrationspfad.
2026-05-22 15:55:59 +02:00
520052e71a KI-AGENT: Telefonie Nebenstellen in Einstellungen integrieren 2026-05-22 15:55:06 +02:00
da9cad1513 KI-AGENT: Scrollbereich der Firmeneinstellungen korrigieren 2026-05-22 15:38:27 +02:00
b44c8d453a KI-AGENT: Nebenstellen und Standardroute für Telefonie ergänzen 2026-05-22 15:24:10 +02:00
bbbdc4d2ae KI-AGENT: Website im Impressum aktualisiert 2026-05-22 15:11:58 +02:00
b15d98f6e9 KI-AGENT: Datenschutzerklärung und Anschrift aktualisiert 2026-05-22 15:10:01 +02:00
f36cbcc207 KI-AGENT: Checkbox im Kontaktformular ausgerichtet 2026-05-22 15:07:29 +02:00
76764eb4c3 KI-AGENT: Kontaktformular und Datenschutzseite ergänzt 2026-05-22 15:03:56 +02:00
0bd0120ec2 KI-AGENT: Zielgruppen-Breite auf Startseite angeglichen 2026-05-21 22:25:20 +02:00
266c07d820 KI-AGENT: Asterisk-Stand ohne FreePBX versionieren 2026-05-21 22:25:01 +02:00
cc34acac3e KI-AGENT: Zielgruppen-Seite für Webseite ergänzt 2026-05-21 22:21:48 +02:00
31b8378b87 KI-AGENT: WebRTC-Codecs für Easybell kompatibel setzen 2026-05-21 22:01:13 +02:00
33ff46744f KI-AGENT: Mehr-Details-Buttons bündig ausgerichtet 2026-05-21 21:57:08 +02:00
c44d8e172d KI-AGENT: LiveKit aus Matrix-Übersicht entfernt 2026-05-21 21:54:08 +02:00
bddb326e18 KI-AGENT: Funktionskacheln um Details erweitert 2026-05-21 21:50:25 +02:00
81cecad668 KI-AGENT: Matrix-Föderation auf Webseite ergänzt 2026-05-21 21:40:58 +02:00
7950315291 KI-AGENT: Matrix-Abschnitt nach Selfhost ausgerichtet 2026-05-21 21:36:06 +02:00
9da30ac2e8 KI-AGENT: VPS-Asterisk Dev-Anbindung ergänzen 2026-05-21 21:34:12 +02:00
fb1ccf91b9 KI-AGENT: Matrix-Stack auf Webseite ergänzt 2026-05-21 21:31:04 +02:00
42bed16e25 KI-AGENT: FreePBX Diagnoseprofil ergänzen 2026-05-21 19:01:31 +02:00
30cbc18b3a KI-AGENT: Easybell Wählstring korrigieren 2026-05-21 18:39:33 +02:00
b6705e84a7 KI-AGENT: Easybell Trunk Vorlage korrigieren 2026-05-21 18:10:28 +02:00
d26fe6dcef KI-AGENT: Easybell SIP-Trunk integrieren 2026-05-21 17:54:58 +02:00
63bf57e720 KI-AGENT: Asterisk Transport-Include korrigieren 2026-05-21 17:44:59 +02:00
1240ffd03b KI-AGENT: FEDEO Asterisk-Trunk beim Neustart bewahren 2026-05-21 17:16:07 +02:00
7a893dfdcb KI-AGENT: NAT Einstellungen für Telekom-Trunk ergänzen 2026-05-21 17:09:23 +02:00
beb91bf5c3 KI-AGENT: Asterisk PJSIP Reload für Trunk korrigieren 2026-05-21 17:00:00 +02:00
9bdd725691 KI-AGENT: Lokale Asterisk-AMI Verbindung korrigieren 2026-05-21 16:53:57 +02:00
821a5f85de KI-AGENT: Lokale Asterisk-Trunk-Dateien teilen 2026-05-21 16:50:44 +02:00
b667a856d4 KI-AGENT: Asterisk-Trunk aus FEDEO anwenden 2026-05-21 16:41:47 +02:00
f6fb607008 KI-AGENT: Telefonie-Trunk in Firmeneinstellungen verschieben 2026-05-21 16:19:56 +02:00
ee6c2d7420 KI-AGENT: Telekom Telefonie an Asterisk anbinden 2026-05-21 16:04:48 +02:00
9e7b5bc0b9 KI-AGENT: Anrufhistorie für Telefonie ergänzen 2026-05-21 15:54:24 +02:00
ba12c46c88 KI-AGENT: Telefonie und Setup trennen 2026-05-21 13:50:25 +02:00
d99cddf5b5 KI-AGENT: Anrufsignalisierung im Softphone ergänzen 2026-05-21 13:38:01 +02:00
df32bf516b KI-AGENT: Telefonieseite scrollbar machen 2026-05-21 13:35:15 +02:00
151f605eb0 KI-AGENT: Asterisk From-Domain für WebRTC setzen 2026-05-21 13:30:53 +02:00
4347a0858d KI-AGENT: SIP-Qualify für Browser-Nebenstellen deaktivieren 2026-05-21 13:28:07 +02:00
8196f8a955 KI-AGENT: SIP-Eingangssignalisierung prüfbarer machen 2026-05-21 12:11:01 +02:00
e9bfa3dc1c KI-AGENT: Eingehende SIP-Anrufe sichtbarer machen 2026-05-21 11:44:20 +02:00
88006be691 KI-AGENT: SIP-Registrierung der Testnebenstellen reparieren 2026-05-20 22:56:33 +02:00
fe23742912 KI-AGENT: Lokale SIP-Nebenstellen erreichbar machen 2026-05-20 22:50:14 +02:00
6abc0dd772 KI-AGENT: SIP-Softphone für lokale Telefonie ergänzen 2026-05-20 22:33:47 +02:00
655a78392b KI-AGENT: Asterisk-Statusprüfung robuster machen 2026-05-20 22:24:13 +02:00
10f03e151d KI-AGENT: Lokalen Asterisk-Teststack ergänzen 2026-05-20 22:18:58 +02:00
4b85ea3d2d KI-AGENT: Lege Selfhost Compose als Standarddatei ab
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 11s
Build and Push Docker Images / build-frontend (push) Successful in 11s
Build and Push Docker Images / build-website (push) Successful in 10s
Build and Push Docker Images / build-docs (push) Successful in 10s
2026-05-20 21:27:41 +02:00
8bed6e2984 KI-AGENT: Lade Selfhost Setup ohne Repo Checkout
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 11s
Build and Push Docker Images / build-frontend (push) Successful in 11s
Build and Push Docker Images / build-website (push) Successful in 11s
Build and Push Docker Images / build-docs (push) Successful in 11s
2026-05-20 21:17:12 +02:00
9c1d3bc04c KI-AGENT: Selfhost Setup für Node Exporter ergänzen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 19s
Build and Push Docker Images / build-frontend (push) Successful in 53s
Build and Push Docker Images / build-website (push) Successful in 20s
Build and Push Docker Images / build-docs (push) Successful in 11s
2026-05-20 21:03:12 +02:00
8df587f9e2 KI-AGENT: Systemstatus und Node Exporter ergänzen 2026-05-20 20:41:48 +02:00
3796bc2953 KI-AGENT: Mobile Matrix-Kommunikation vollständig integrieren 2026-05-20 20:38:48 +02:00
2278dfa714 KI-AGENT: Call UX im Chat verbessern 2026-05-20 20:32:02 +02:00
1a5c69fcfb KI-AGENT: Live-Sync und Nachrichtenaktionen im Chat ergänzen 2026-05-20 20:27:38 +02:00
a671ae392d KI-AGENT: Mitgliederverwaltung und Suche im Chat umsetzen 2026-05-20 20:21:18 +02:00
4c58d175a0 KI-AGENT: Chat Anhänge und Nachrichteninteraktionen abrunden 2026-05-20 20:12:02 +02:00
bc655f0e06 KI-AGENT: Mobile Version auf 2.0.0 anheben
- App-Version auf 2.0.0 gesetzt
- iOS Buildnummer auf 3 gesetzt
- Package-Lock auf neue Mobile-Version aktualisiert
2026-05-20 20:09:13 +02:00
22bcf01fa8 KI-AGENT: Mobile Bundle-ID für TestFlight anpassen
- iOS Bundle Identifier und Android Package auf software.federspiel.fedeo gesetzt
- TestFlight-Dokumentation aktualisiert
- Vertriebs-Screenshots des Mobile-Dashboards ergänzt
2026-05-20 20:05:21 +02:00
bf8a3386d7 KI-AGENT: Mobile TestFlight Build vorbereiten
- EAS-Profil und Scripts für TestFlight ergänzt
- Node 22 für Mobile-Builds festgelegt und README aktualisiert
- Expo-SDK-Abhängigkeiten für expo-doctor angeglichen
2026-05-20 19:44:24 +02:00
d182231448 KI-AGENT: Selfhost-Codeblock zentriert 2026-05-19 22:41:11 +02:00
0a32ae77cd KI-AGENT: Selfhost-Codeblock schmaler ausgerichtet 2026-05-19 22:35:52 +02:00
98c95483d8 KI-AGENT: Selfhost-Script als Codeblock eingebaut 2026-05-19 22:32:21 +02:00
bcde1da84f KI-AGENT: Zeige absoluten Compose Pfad im Selfhost Setup 2026-05-19 22:19:32 +02:00
6157d7e27d KI-AGENT: Nutze Terminaleingabe im Selfhost Installer
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 11s
Build and Push Docker Images / build-frontend (push) Successful in 10s
Build and Push Docker Images / build-website (push) Successful in 11s
Build and Push Docker Images / build-docs (push) Successful in 11s
2026-05-19 22:14:51 +02:00
0cfa6a691b KI-AGENT: Ergänze Selfhost Curl Installer
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 11s
Build and Push Docker Images / build-frontend (push) Successful in 11s
Build and Push Docker Images / build-website (push) Successful in 11s
Build and Push Docker Images / build-docs (push) Successful in 11s
2026-05-19 22:06:13 +02:00
14470da7dc KI-AGENT: Webseite in Docker-Workflow aufgenommen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 18s
Build and Push Docker Images / build-frontend (push) Successful in 10s
Build and Push Docker Images / build-website (push) Successful in 26s
Build and Push Docker Images / build-docs (push) Successful in 10s
2026-05-19 22:01:54 +02:00
85ac33c334 KI-AGENT: Neue Logo-Dateien in Webseite verwendet 2026-05-19 21:58:47 +02:00
9e38a488c8 KI-AGENT: Impressum auf Federspiel Technology aktualisiert 2026-05-19 21:49:56 +02:00
ed6283b9e1 KI-AGENT: Farbgebung der Webseite auf Grün aktualisiert 2026-05-19 21:44:09 +02:00
2d2e8552f0 KI-AGENT: Neue Nuxt-Webseite für FEDEO erstellt 2026-05-19 21:40:27 +02:00
25ed99b356 KI-AGENT: Ergänze geführtes Selfhost Setup 2026-05-19 20:45:54 +02:00
6cc7dc87ad KI-AGENT: Überspringe fehlende S3-Dateien beim Mandantenexport 2026-05-19 19:47:38 +02:00
697abc99fa KI-AGENT: Starte Matrix im Selfhost ohne Profil 2026-05-19 19:00:35 +02:00
bace26c084 KI-AGENT: Vereinfache Matrix Selfhost auf eine Domain
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 51s
Build and Push Docker Images / build-docs (push) Successful in 11s
2026-05-19 18:49:04 +02:00
274f3d5795 KI-AGENT: Ergänze Matrix im Selfhost-Stack 2026-05-19 18:40:30 +02:00
168d2fce6e KI-AGENT: StandardEntity Empty-State vereinheitlichen
Rendert die StandardEntity-Tabelle auch ohne Einträge und nutzt den gemeinsamen Empty-State statt der separaten Card.
2026-05-19 18:40:10 +02:00
6dcd8b1863 KI-AGENT: Tabellen-Empty-States ohne JSON rendern
Ersetzt ungültige UTable-Empty-Props durch einen gemeinsamen Empty-State-Slot, damit leere Tabellen keine Objekt-/JSON-Ausgabe mehr anzeigen.
2026-05-19 18:36:54 +02:00
81ce9d263d KI-AGENT: Ergänze fehlende Profil-Verfügbarkeitsmigration
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 10s
Build and Push Docker Images / build-docs (push) Successful in 10s
2026-05-19 18:25:52 +02:00
6455be81bd KI-AGENT: Beleg-Relationswerte vor dem Speichern normalisieren
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 51s
Build and Push Docker Images / build-docs (push) Successful in 11s
2026-05-19 16:53:53 +02:00
9cde630562 KI-AGENT: Datumswerte in Beleg-Relationen bereinigen 2026-05-19 16:48:22 +02:00
48d101e139 KI-AGENT: Fehlerhafte Serienausführung bei Belegen abfangen 2026-05-19 16:31:57 +02:00
167e9a40c3 KI-AGENT: Ergänze Kalender-Abo für Mitarbeiterprofile 2026-05-19 16:26:49 +02:00
f9d3f10eae Dateityp-Belegarten in Detailinfo anzeigen 2026-05-19 15:26:44 +02:00
6d9bceb63f Doppelte Abschlagsrechnung in Auswahl entfernen 2026-05-19 15:25:04 +02:00
e29e84898b Abschlagsrechnung als Dateityp ergänzen 2026-05-19 15:21:44 +02:00
1ccabbedcd Dateityp-Belegarten in Listen anzeigen 2026-05-19 15:20:38 +02:00
24febf4c95 Dateityp-Belegarten als Auswahl pflegen 2026-05-19 15:12:27 +02:00
5fc7cc9604 Dateimodal überarbeiten und Dateitypen pflegen 2026-05-19 12:47:51 +02:00
941f1d819b KI-AGENT: Leite Termine nach dem Speichern zurück zur Plantafel 2026-05-19 12:31:39 +02:00
58c47fa8f7 KI-AGENT: Ergänze wiederholende Termine für Kalender und Plantafel 2026-05-19 12:27:17 +02:00
ea392af094 Ergänze Entwurfsstatus für Termine und Plantafel 2026-05-19 12:18:30 +02:00
0ac22d346f KI-AGENT: Bildvorschau im Chat authentifiziert laden 2026-05-19 10:55:36 +02:00
26ffc4421a KI-AGENT: Anhänge im Chat über Matrix unterstützen 2026-05-19 10:51:33 +02:00
7caa37378b KI-AGENT: Chat Benachrichtigungen und Ungelesen-Zähler umsetzen 2026-05-19 08:39:26 +02:00
227a88b24b KI-AGENT: Chatgruppen einklappbar machen 2026-05-19 08:33:17 +02:00
0fb469c9b0 KI-AGENT: Chaträume sortieren und Matrix-Setup verschieben 2026-05-19 08:31:40 +02:00
5b3445c2dc KI-AGENT: Projekträume und Direktnachrichten integrieren 2026-05-19 08:27:39 +02:00
716de8a503 KI-AGENT: Verschlüssele Bankverbindungen beim Import neu 2026-05-19 08:19:25 +02:00
817d0e814b KI-AGENT: Erhalte Bankkonten und Buchungszuordnungen beim Import
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 19s
Build and Push Docker Images / build-frontend (push) Successful in 11s
Build and Push Docker Images / build-docs (push) Successful in 11s
2026-05-18 22:08:53 +02:00
75d5e2b72d Revert "KI-AGENT: Exportiere Sachkonten beim Mandantenumzug"
This reverts commit 30aaf141c7.
2026-05-18 22:07:47 +02:00
30aaf141c7 KI-AGENT: Exportiere Sachkonten beim Mandantenumzug 2026-05-18 22:05:53 +02:00
c7ba7a9cc5 KI-AGENT: Importiere Export in bestehenden Zielmandanten
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 49s
Build and Push Docker Images / build-docs (push) Successful in 11s
2026-05-18 21:49:12 +02:00
1c68e6b724 KI-AGENT: Aktiviere importierten Mandanten für Zieladmin 2026-05-18 21:47:28 +02:00
cc3c405473 KI-AGENT: Überspringe generierte Spalten beim Mandantenimport
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 10s
Build and Push Docker Images / build-docs (push) Successful in 11s
2026-05-18 21:40:47 +02:00
ff70338b21 KI-AGENT: Serialisiere JSON-Felder beim Mandantenimport
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 11s
Build and Push Docker Images / build-docs (push) Successful in 10s
2026-05-18 21:35:16 +02:00
bb3b842be1 KI-AGENT: Ergänze Mandantenexport und Import
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 18s
Build and Push Docker Images / build-frontend (push) Successful in 51s
Build and Push Docker Images / build-docs (push) Successful in 11s
2026-05-18 21:23:18 +02:00
9c6a6a841a KI-AGENT: Fange fehlende Dokument-Auswahldaten ab 2026-05-18 21:15:34 +02:00
b7b913035e KI-AGENT: Briefpapier-Upload und Dateianzeige korrigieren 2026-05-18 21:10:41 +02:00
454e9ee3c9 KI-AGENT: Briefpapierpflege im Frontend ergänzen 2026-05-18 21:06:50 +02:00
01846d488b KI-AGENT: Traefik-Netzwerk für Selfhosting festlegen 2026-05-18 20:56:10 +02:00
80b2b1d097 KI-AGENT: Profil-Verfügbarkeitsmigration im Journal ergänzen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 1m22s
Build and Push Docker Images / build-frontend (push) Successful in 2m27s
Build and Push Docker Images / build-docs (push) Successful in 59s
2026-05-18 20:15:58 +02:00
f5755993b5 KI-AGENT: Sharp im Backend-Container für Linux installieren 2026-05-18 20:12:19 +02:00
0f56102030 KI-AGENT: Wiederholte Sammel-Migration leeren 2026-05-18 20:10:22 +02:00
60d846baa9 KI-AGENT: Doppelte Vertragstypen-Migration bereinigen 2026-05-18 20:08:24 +02:00
a28b910d4d KI-AGENT: Doppelte Zeiterfassungs-Migration bereinigen 2026-05-18 20:02:29 +02:00
4aeefb2b83 KI-AGENT: Zentrale Benachrichtigungsengine mit Desktop Push umsetzen 2026-05-18 19:51:08 +02:00
24c09d7891 KI-AGENT: Kamera und Bildschirmfreigabe getrennt anzeigen 2026-05-18 19:28:53 +02:00
77eabe7e18 KI-AGENT: FEDEO-Call-Erlebnis ausbauen 2026-05-18 19:24:12 +02:00
e4073e01ad KI-AGENT: Lokale LiveKit-Verbindung für FEDEO-Calls korrigieren 2026-05-18 19:18:43 +02:00
248da3412c KI-AGENT: LiveKit-Calls nativ in FEDEO integrieren 2026-05-18 19:15:36 +02:00
c93ea4284d KI-AGENT: Matrix-Einbettung stabilisieren 2026-05-18 18:56:37 +02:00
7c68ce61f2 KI-AGENT: Matrix-Anrufe im Chat vorbereiten 2026-05-18 18:38:21 +02:00
f6dd37b458 KI-AGENT: Matrix-Teilnehmer synchronisieren 2026-05-18 18:33:17 +02:00
bb54a8779e KI-AGENT: Chaträume im Frontend verwalten 2026-05-18 18:23:14 +02:00
6e14f48770 KI-AGENT: Matrix-Räume persistent verwalten 2026-05-18 18:19:23 +02:00
4d24e3a657 KI-AGENT: Erstzugriff und Mandanten-Grunddaten für Selfhosting ergänzen 2026-05-18 18:17:23 +02:00
f33ccf730a KI-AGENT: Matrix-Raum-API verallgemeinern 2026-05-18 18:12:26 +02:00
8824b1c9c8 KI-AGENT: Selfhosting für Secrets, Compose und Migrationen vorbereiten 2026-05-18 18:06:03 +02:00
571c24f250 KI-AGENT: Chat in eigene Kommunikationsseite auslagern 2026-05-18 18:01:54 +02:00
b03af21e97 KI-AGENT: Matrix-Login-Rate-Limits vermeiden 2026-05-18 17:55:41 +02:00
b1e102ca5d KI-AGENT: Matrix-Chat Rate-Limits reduzieren 2026-05-18 17:49:31 +02:00
8b40be7909 KI-AGENT: Matrix-Chat live aktualisieren 2026-05-18 17:45:56 +02:00
655459a46b KI-AGENT: Nativen Matrix-Chat in FEDEO starten 2026-05-18 17:41:31 +02:00
5fca7792a2 KI-AGENT: Scrollen auf Kommunikationsseite ermöglichen 2026-05-18 17:35:10 +02:00
30b6ffcc20 KI-AGENT: Matrix-Chat in FEDEO einbetten 2026-05-18 17:29:34 +02:00
7f66f66cfa KI-AGENT: Matrix-Räume in FEDEO provisionieren 2026-05-18 17:24:46 +02:00
d0de3cb92e KI-AGENT: Matrix-Mandanten-Space provisionieren 2026-05-18 17:11:52 +02:00
c893574cb1 KI-AGENT: Matrix-Kontoerstellung nutzbarer machen 2026-05-18 16:59:35 +02:00
eb2dd03ef9 KI-AGENT: Matrix-Kommunikation im Frontend anbinden 2026-05-18 15:42:10 +02:00
b322d0c173 KI-AGENT: Erste Matrix-Backendintegration ergänzen 2026-05-18 15:37:12 +02:00
54ae136f0d KI-AGENT: LiveKit-Start im Matrix-Stack korrigieren 2026-05-18 15:33:34 +02:00
00e1e88dd9 KI-AGENT: Lokalen Matrix-Entwicklungsstack ergänzen 2026-05-18 15:24:43 +02:00
3984e218db KI-AGENT: Matrix-Stack in Docker Compose vorbereiten 2026-05-18 14:58:27 +02:00
d9c3c8d07c KI-AGENT: Matrix-Kommunikationslösung entwerfen 2026-05-18 14:38:41 +02:00
c6a0d59c29 SEPA-Exportdatei aus Mandaten erzeugen #182 2026-05-15 18:36:48 +02:00
9592e2b062 SEPA-Mandate in Verträge und Ausgangsrechnungen einbauen #183 2026-05-15 18:13:29 +02:00
d522cbb49d Bankverbindungs-Buttons bei SEPA-Mandaten ergänzen #183 2026-05-15 18:06:43 +02:00
8d7bc2e97c SEPA-Mandatsauswahlen als Wörterbücher pflegen #183 2026-05-15 18:00:57 +02:00
44017a768b Ausgehende SEPA-Mandate einführen #183 2026-05-15 17:47:11 +02:00
683d073b6e KI-AGENT: MCP-Belegpositionen für Angebote normalisieren 2026-05-15 17:11:31 +02:00
cb939f2197 DATEV-Export Datumsformat korrigieren #181
KI-AGENT: Normalisiert Export-Zeiträume und Belegdatumsfelder vor der DATEV-Ausgabe auf Europe/Berlin, damit per UI gewählte Daten nicht durch UTC-Verschiebung auf den Vortag fallen.
2026-05-15 16:54:34 +02:00
0e71899c57 DATEV-BU-Schlüssel für Ausgangsbelege entfernen #179 2026-05-13 09:52:22 +02:00
6b82f2b629 DATEV-Erlöskonten für Ausgangsbelege aufteilen #179 2026-05-13 09:48:52 +02:00
9ba5f26efc MCP Upload für Eingangsbelege ergänzen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 23s
Build and Push Docker Images / build-frontend (push) Successful in 1m2s
Build and Push Docker Images / build-docs (push) Successful in 15s
2026-05-12 19:04:37 +02:00
82f2143dd1 MCP Tokenverwaltung in Firmeneinstellungen ergänzen 2026-05-12 18:25:30 +02:00
4e49dd18a1 MCP um dauerhafte tenantgebundene Tokens erweitern
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 23s
Build and Push Docker Images / build-frontend (push) Successful in 1m4s
Build and Push Docker Images / build-docs (push) Successful in 15s
2026-05-12 17:39:20 +02:00
252021acee KI-AGENT: Entwürfe bei offenen Belegen anzeigen #180 2026-05-12 11:32:58 +02:00
eae321b364 DATEV-Steuerschlüssel für 13b-Ausgangsrechnungen setzen #179 2026-05-12 11:21:09 +02:00
5a2682c835 KI-AGENT: Wiki-Neuanlage repariert #178
Der Wiki-Neu-Button nutzt nun das aktuelle DropdownMenu mit onSelect-Callbacks, sodass neue Seiten und Ordner wieder erstellt werden können.
2026-05-12 10:07:55 +02:00
34f537238e Kundenanlage mit aktiven Standardwerten vorbelegen #120
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 27s
Build and Push Docker Images / build-frontend (push) Successful in 1m10s
Build and Push Docker Images / build-docs (push) Successful in 16s
2026-05-11 18:20:59 +02:00
64df33f0fa Ausgangsbeleg-Toolbar aufräumen #110
Gruppiert Verknüpfungen in ein Dropdown und lädt Bankbuchungen für Ausgangsbelege gezielt mit Bankstatement-Relation nach, damit das Bankbuchungsdatum korrekt angezeigt wird.
2026-05-11 18:15:01 +02:00
94ab3350ec Belegansichten um Bankbuchungsdatum erweitern #110
Zeigt Bankbuchungsdaten in Ausgangsbelegen direkt an und ergänzt Bankdetails im Modal. Überarbeitet die Eingangsbeleg-Showansicht zu einer echten Lesedarstellung mit Bankbuchungsdaten und Positionsübersicht.
2026-05-11 18:04:05 +02:00
aa162dcad3 KI-AGENT: Erweitert Länderauswahl für Lieferanten (#157)
Die Länderauswahl wird beim Laden der Spezialressource um eine vollständige deutschsprachige Standardliste ergänzt. Bestehende Datenbankeinträge bleiben erhalten und überschreiben die Standardwerte.
2026-05-11 17:52:59 +02:00
c42e57494a Behebt Breadcrumb-Navigation im Dateimanager
Issue 170: Die Dateimanager-Breadcrumbs nutzen jetzt die Nuxt-UI-Items-API, zeigen den aktuellen Ordnerpfad an und erlauben die Navigation zu übergeordneten Ordnern über die Route.
2026-05-11 17:41:39 +02:00
582af62fcb Korrigiert Kassenbuch Navbar Struktur
Die Kassenbuch-Listenansicht rendert die DashboardNavbar nun wie andere Listenseiten direkt oben. Die Detailansicht nutzt dieselbe Struktur und hält den Inhalt im PanelContent.
2026-05-11 17:30:42 +02:00
743c0e8772 Verschiebt Kassenbuch Infos in Navbar
Die Detailinformationen zum Kassenbuch werden nun in der Navbar angezeigt. Die separate Kartenzeile oberhalb der Buchungsmaske entfällt.
2026-05-11 17:27:46 +02:00
d4c39d7d44 Passt Kassenbuch Ansicht an
Kassenbücher werden nun zuerst tabellarisch angezeigt. Das Erstellen einer Barkasse erfolgt über ein Modal und einzelne Kassenbücher öffnen sich über eine Detailseite.
2026-05-11 17:25:44 +02:00
e60188f043 Dokument-Steuertypen im FEDEO MCP ergänzen
Erweitert die Ausgangsbeleg-Tools um explizite Dokument-Steuertypen. Der MCP listet die unterstützten Steuertypen, validiert taxType als Dokumentfeld und setzt bei 13b UStG, 19 UStG und 12.3 UStG die Positions-USt analog zur Oberfläche auf 0 Prozent.
2026-05-11 17:25:10 +02:00
ca4f1ba1c0 Eingangsbelege im FEDEO MCP bearbeitbar machen
Ergänzt MCP-Tools zum Prüfen, Bearbeiten, Erstellen, Buchen und Archivieren von Eingangsbelegen. Die Validierung spiegelt die Pflichtregeln aus der FEDEO-Oberfläche und verhindert das Buchen unvollständiger Belege.
2026-05-11 17:17:09 +02:00
5fe823f52a Implementiert Kassenbuch für Barkassen
Barkassen können als manuelle Bankkonten angelegt werden. Kassenbuchungen erzeugen Bankbewegungen mit Gegenkonto und sind über eine neue Buchhaltungsseite erreichbar.
2026-05-11 17:13:49 +02:00
1969610130 Finalisieren von MCP-Ausgangsbelegen korrigieren
Passt die Ausgangsbeleg-Tools an die bestehende FEDEO-Logik an: Entwürfe erhalten keine Belegnummer, Create und Update akzeptieren keine manuellen Nummern mehr, und die Nummernvergabe erfolgt ausschließlich über ein separates Finalisieren-Tool.
2026-05-11 16:38:30 +02:00
2bf52b35fe Ausgangsbelege im FEDEO MCP ergänzen
Erweitert den Accounting-MCP um lesende und schreibende Tools für Ausgangsbelege. Belege können gelistet, geladen, als Entwurf erstellt, aktualisiert und archiviert werden; optional wird beim Schreiben eine Belegnummer aus dem passenden Nummernkreis gezogen.
2026-05-11 16:33:28 +02:00
f01881a6ce Stammdaten-Tools für FEDEO MCP ergänzen
Ergänzt eine eigene MCP-Toolgruppe für Stammdaten. Enthalten sind read-only Werkzeuge für Kunden, Lieferanten, Kontakte, Artikel, Leistungen, Kostenstellen, Niederlassungen, Teams, Fahrzeuge, Inventar und Einheiten.
2026-05-11 13:12:01 +02:00
a185c6eb11 FEDEO MCP-Tools für Organisation erweitern
Ergänzt MCP-Tools für Kunden-, Projekt-, Anlagen- und Terminabfragen sowie das Laden einzelner Bankumsätze. Aufgaben können nun zusätzlich gezielt archiviert werden.
2026-05-11 13:07:11 +02:00
a8450fc0c6 MCP-Server für Buchhaltung und Organisation ergänzen
Fügt einen geschützten MCP-JSON-RPC-Endpunkt mit Buchhaltungs-Tools und Aufgaben-Tools hinzu. Berechtigungen werden rollenbasiert pro Mandant geprüft und die Auth-Logik berücksichtigt nun alle Rollen eines Nutzers.
2026-05-11 12:43:58 +02:00
0f5275b870 Ausgangsrechnungen zeigen korrektes Belegdatum
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 2m34s
Build and Push Docker Images / build-frontend (push) Successful in 1m12s
Build and Push Docker Images / build-docs (push) Successful in 17s
2026-05-08 20:24:58 +02:00
4f37811dcc Suche im zentralen Logbuch hinzufügen 2026-05-08 20:20:44 +02:00
d7eced3e77 Vertragstypen für Änderungsanfragen pflegen 2026-05-08 20:09:24 +02:00
6a5c1e844d Vertragstypen im Kundenportal freigeben 2026-05-08 20:04:26 +02:00
5dc44e571f Kundenportal Vertragsanfragen ergänzen 2026-05-08 20:01:57 +02:00
2b1a9a456b Ausgangsbelege nach offenen Belegen filterbar machen 2026-05-08 19:36:48 +02:00
bf5d7aaed2 Dateien in Organisation verschoben 2026-05-08 19:27:00 +02:00
e166248c0d Mitarbeiternavigation neu gruppiert 2026-05-08 19:25:07 +02:00
cba4ea52e8 Bearbeiten-Aktion im Plantafel-Mitarbeitermodal ergänzen 2026-04-29 16:37:12 +02:00
0f14f7ac3d Verfügbarkeitshinweise für Mitarbeiter und Plantafel-Details ergänzen 2026-04-29 16:33:39 +02:00
2d26cedaa3 Benutzeranlage direkt aus Mitarbeiterprofil ermöglichen 2026-04-29 16:23:35 +02:00
d5aed2140e Plantafel-Modal für Profile ohne Benutzerzuordnung absichern 2026-04-29 16:19:03 +02:00
cfc5efb556 Plantafel um Mitarbeiterdetails mit Resturlaub erweitern 2026-04-29 16:12:13 +02:00
898a5459fa Ergänze Team-Zuordnung im Mitarbeiterimport 2026-04-29 15:58:32 +02:00
3b7bcb7940 Erweitere Dry-Run-Ausgabe für Mitarbeiterimport 2026-04-29 15:51:07 +02:00
2aaff0088e Füge Branch-Mapping für Mitarbeiterlisten-Import von Tenant 41 hinzu 2026-04-29 15:41:42 +02:00
e9bbc196f7 Füge Importskript für Mitarbeiterlisten mit Tenant- und Niederlassungszuordnung hinzu 2026-04-28 14:06:09 +02:00
20818beb3a Deaktivated Verify Docs Sync
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 27s
Build and Push Docker Images / build-frontend (push) Successful in 1m8s
Build and Push Docker Images / build-docs (push) Successful in 1m25s
2026-04-27 09:20:32 +02:00
6aa69cb68b Deaktivated Verify Docs Sync
Some checks failed
Build and Push Docker Images / build-backend (push) Has been cancelled
Build and Push Docker Images / build-frontend (push) Has been cancelled
Build and Push Docker Images / build-docs (push) Has been cancelled
2026-04-27 09:19:33 +02:00
a021d3d15c Time Changes
Some checks failed
Build and Push Docker Images / verify-docs-sync (push) Failing after 9s
Build and Push Docker Images / build-backend (push) Has been skipped
Build and Push Docker Images / build-frontend (push) Has been skipped
Build and Push Docker Images / build-docs (push) Has been skipped
2026-04-27 09:17:36 +02:00
bb61caed6d Unterkostenstellen in der Kostenstellenauswertung korrekt auflösen 2026-04-24 23:03:23 +02:00
d3ab03da7e Kostenstellenhierarchie und Auswertung mit Unterkostenstellen ergänzt 2026-04-24 22:56:33 +02:00
5869f88c1a Vereinheitliche Empty States in Tabellen 2026-04-24 14:42:53 +02:00
50c76b67c7 Serienvorlagen in Liquiditätsprognose einplanen 2026-04-23 22:15:50 +02:00
f4edcc2d44 Rechnungsentwürfe optional wie Rechnungen verwenden 2026-04-23 21:49:45 +02:00
35ef3a7cf8 USt-Auswertung in Liquiditätsprognose integrieren 2026-04-23 21:44:59 +02:00
4783971000 Rechnungsentwürfe optional in Prognose anzeigen
Zeigt Rechnungsentwürfe eingeklammert als optionalen Einfluss in der Liquiditätsprognose an, ohne den eigentlichen Endstand zu verändern.
2026-04-23 21:29:14 +02:00
c085b1e4d5 Liquiditätsprognose besser nachvollziehbar machen
Ergänzt Herleitung, Einflussfaktoren, größte Treiber und eine Tagesaufschlüsselung, damit die Prognosewerte Schritt für Schritt nachvollzogen werden können.
2026-04-23 21:21:15 +02:00
46b08b29b9 Regelmäßige Bewegungen auf Ausgaben begrenzen
Berücksichtigt in der Liquiditätsprognose nur noch negative, also ausgehende, wiederkehrende Bankbewegungen aus Heuristik und KI-Erkennung.
2026-04-23 21:18:11 +02:00
5cc41f9a2d Manuelle Buchungen in Liquiditätsprognose korrekt verrechnen
Berechnet offene Eingangsbelege jetzt mit Absolutbeträgen, damit manuelle Buchungen und Bankzuordnungen unabhängig vom gespeicherten Vorzeichen korrekt in der Prognose erscheinen.
2026-04-23 21:13:04 +02:00
edec670ee0 Eingangsbelege um offenen Betrag ergänzen 2026-04-23 21:06:44 +02:00
41e5a4021b Manuelle Buchungen um zuweisbare Eingangsbelege erweitern 2026-04-23 17:52:56 +02:00
9c608cbf71 Manuelle Buchungen im Menü hinter Bank verschieben 2026-04-23 17:39:22 +02:00
543952dbf8 Manuelle Buchungen Select ohne Leerwert absichern 2026-04-23 17:36:32 +02:00
2f7819e309 Manuelle Buchungen um funktionsfähigen Steuerschlüssel und volle Beschreibungsbreite korrigieren 2026-04-23 17:35:32 +02:00
7799cbce80 Manuelle Buchungen um volle Beschreibungsbreite und einklappbare Kontenlisten ergänzen 2026-04-23 17:33:35 +02:00
0284ea8726 Manuelle Buchungen um DATEV-Steuerschlüssel und getrennte Soll/Haben-Auswahl erweitern 2026-04-23 17:24:58 +02:00
743bf0660c Manuelle Buchungen in Statementallocations integrieren 2026-04-23 16:28:44 +02:00
df4b591be4 Liquiditätsprognose zwischenspeichern
Lädt die Liquiditätsprognose aus einem lokalen Cache und erstellt sie nur noch manuell über den Refresh-Button in der Toolbar neu.
2026-04-23 16:15:04 +02:00
86e0743cbb Bezahlte Eingangsbelege aus Liquiditätsprognose entfernen
Berücksichtigt das Bezahlt-Kennzeichen und korrigiert die Verrechnung von Bankzuordnungen bei offenen Eingangsbelegen.
2026-04-23 16:06:57 +02:00
aaf91ea15e Belege und Bankmuster in Liquiditätsprognose verwalten
Ermöglicht das Öffnen von Belegen aus der Liquiditätsprognose und das Abschließen erkannter regelmäßiger Bankbewegungen, die anschließend aus der Prognose herausgerechnet werden.
2026-04-23 16:03:37 +02:00
cb71e9d294 Archivierte Belege aus Liquiditätsprognose ausschließen
Sichert die Liquiditätsprognose zusätzlich gegen archivierte Ausgangs- und Eingangsbelege sowie deren Zuordnungen ab.
2026-04-23 15:56:46 +02:00
75148b2718 Liquiditätsprognose für Auswertungen ergänzt
Erstellt einen KI-gestützten Backend-Endpunkt für die Liquiditätsprognose, ergänzt die Auswertungsseite mit Verlauf, offenen Belegen und regelmäßigen Bankbewegungen und verlinkt die Funktion in der Navigation.
2026-04-23 15:52:41 +02:00
81b4eee1e8 Vereinfache Bedienungsdoku und ergänze Bankportal-Anleitung 2026-04-22 19:43:37 +02:00
0fbda27609 Verschlanke Dokumentation auf Bedienung und leite Einstieg direkt dorthin 2026-04-22 19:27:17 +02:00
3562d55a12 Richte Nutzerdoku auf Bedienungsanleitung mit Frontend-Seitenkategorie aus 2026-04-22 19:21:32 +02:00
6224a25c38 Gestalte Docs-Landing und Header im Nuxt-UI-Template-Stil 2026-04-22 19:13:11 +02:00
63b1c563c1 Stelle docs-site auf Nuxt-UI-Docs-Template-Stil um 2026-04-22 19:07:15 +02:00
76f86e87c1 Behebe 404 im Nuxt-Devserver durch _path-basierte Content-Abfrage 2026-04-22 18:59:11 +02:00
8c458f4953 Ersetze Docusaurus vollständig durch Nuxt-Content-Docs-App
All checks were successful
Build and Push Docker Images / verify-docs-sync (push) Successful in 9s
Build and Push Docker Images / build-backend (push) Successful in 14s
Build and Push Docker Images / build-frontend (push) Successful in 13s
Build and Push Docker Images / build-docs (push) Successful in 1m47s
2026-04-22 18:16:00 +02:00
d704e343fc Behebe Docs-Dockerbuild durch korrekten Build-Pfad
All checks were successful
Build and Push Docker Images / verify-docs-sync (push) Successful in 8s
Build and Push Docker Images / build-frontend (push) Successful in 14s
Build and Push Docker Images / build-backend (push) Successful in 14s
Build and Push Docker Images / build-docs (push) Successful in 42s
2026-04-22 17:57:15 +02:00
4882da0d35 Stabilisiere Docs-Auslieferung unter /docs mit Traefik StripPrefix
Some checks failed
Build and Push Docker Images / verify-docs-sync (push) Successful in 7s
Build and Push Docker Images / build-backend (push) Successful in 15s
Build and Push Docker Images / build-frontend (push) Successful in 14s
Build and Push Docker Images / build-docs (push) Failing after 41s
2026-04-22 16:06:02 +02:00
1908a6441d Behebe Nginx Redirect-Loop für Docusaurus unter /docs
All checks were successful
Build and Push Docker Images / verify-docs-sync (push) Successful in 8s
Build and Push Docker Images / build-backend (push) Successful in 15s
Build and Push Docker Images / build-frontend (push) Successful in 14s
Build and Push Docker Images / build-docs (push) Successful in 43s
2026-04-22 15:25:42 +02:00
a4735818fb Behebe Docs-Build in CI durch stabile Webpack-Overrides
All checks were successful
Build and Push Docker Images / verify-docs-sync (push) Successful in 8s
Build and Push Docker Images / build-backend (push) Successful in 14s
Build and Push Docker Images / build-frontend (push) Successful in 14s
Build and Push Docker Images / build-docs (push) Successful in 1m48s
2026-04-22 15:09:12 +02:00
4fb3d3c8a0 Stabilisiere Workflow-Imagepfad auf flfeders/fedeo für Compose-Kompatibilität
Some checks failed
Build and Push Docker Images / verify-docs-sync (push) Successful in 8s
Build and Push Docker Images / build-backend (push) Successful in 14s
Build and Push Docker Images / build-frontend (push) Successful in 14s
Build and Push Docker Images / build-docs (push) Failing after 20s
2026-04-22 14:58:30 +02:00
30dc99e4e0 Integriere Docusaurus in Haupt-Compose mit TLS unter /docs 2026-04-22 14:48:11 +02:00
9fea18b215 Behebe fehlschlagenden Docs-Workflow durch deterministische Doku-Generierung
Some checks failed
Build and Push Docker Images / verify-docs-sync (push) Successful in 8s
Build and Push Docker Images / build-backend (push) Successful in 2m50s
Build and Push Docker Images / build-frontend (push) Successful in 3m18s
Build and Push Docker Images / build-docs (push) Failing after 1m29s
2026-04-22 14:38:51 +02:00
75c15c14c4 Commit Doku
Some checks failed
Build and Push Docker Images / verify-docs-sync (push) Failing after 8s
Build and Push Docker Images / build-backend (push) Has been skipped
Build and Push Docker Images / build-frontend (push) Has been skipped
Build and Push Docker Images / build-docs (push) Has been skipped
2026-04-22 14:35:22 +02:00
b27b00f59c Erweitere CI-Workflow um Doku-Sync-Prüfung und Docs-Image-Deploy
Some checks failed
Build and Push Docker Images / verify-docs-sync (push) Failing after 10s
Build and Push Docker Images / build-backend (push) Has been skipped
Build and Push Docker Images / build-frontend (push) Has been skipped
Build and Push Docker Images / build-docs (push) Has been skipped
2026-04-21 21:40:55 +02:00
1637d4bd91 Bereite Docusaurus-Deploy mit Docker und eigener Docs-Site vor 2026-04-21 19:45:16 +02:00
8114a8c645 Füge versionierbare Funktionsdokumentation mit automatischer Synchronisierung hinzu 2026-04-21 19:35:55 +02:00
0b7d20d946 Fix materialComp und PWA DEVOptions
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 15s
Build and Push Docker Images / build-frontend (push) Successful in 1m2s
2026-04-15 10:38:50 +02:00
849e24092e Added Teams
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 26s
Build and Push Docker Images / build-frontend (push) Successful in 1m7s
Minor Rework of Plantafel
2026-04-14 21:17:05 +02:00
6fcaf3f65c Fix Export Date Select
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 2m52s
Build and Push Docker Images / build-frontend (push) Successful in 1m7s
2026-04-08 20:24:33 +02:00
dce0046e63 Fix Ausgangsbeleg kopieren 2026-04-08 20:24:15 +02:00
02b5769049 Fix BWA Calc 2026-04-08 18:52:16 +02:00
f125617af0 Kundenportal arbeiten 2026-04-08 18:52:04 +02:00
d9e5df07bf serialinvoice fix
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 1m3s
2026-04-01 20:32:16 +02:00
7996c746c3 Add External Link
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 27s
Build and Push Docker Images / build-frontend (push) Successful in 1m3s
Fix Plantafel
2026-03-27 21:41:20 +01:00
f679eb3624 Fix Serial invoice
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 2m58s
2026-03-26 23:00:56 +01:00
7ad44544cf Fix #119
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 2m36s
Build and Push Docker Images / build-frontend (push) Successful in 1m5s
Fix #153
2026-03-25 17:20:47 +01:00
669bcd93ab Tidying in TenantDropdown.vue 2026-03-25 17:14:15 +01:00
aee45e29fd Added Abschreibungen 2026-03-25 17:14:03 +01:00
42e0d7b35e Added Abschreibungen 2026-03-25 17:13:59 +01:00
f6c9875320 Fix #144
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 2m40s
Build and Push Docker Images / build-frontend (push) Successful in 1m2s
2026-03-25 16:04:17 +01:00
05f3b678c4 Fix for Incoming Invoices 2026-03-25 16:03:54 +01:00
eb718021fd Added Kostenschätzung und Packschein
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 22s
Build and Push Docker Images / build-frontend (push) Successful in 59s
2026-03-25 15:38:28 +01:00
01b4d0f973 Fix for missing Phases
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 23s
Build and Push Docker Images / build-frontend (push) Successful in 59s
2026-03-25 15:19:33 +01:00
c29494dc0d redone admin
added branches
2026-03-25 14:59:44 +01:00
809a37a410 fix workflows 2026-03-25 14:59:32 +01:00
232e3f3260 Fix copy created document modal 2026-03-25 14:59:19 +01:00
b2657f5d52 Fix Worklow Form 2026-03-25 14:58:55 +01:00
cee0e1fa7d Fix Phases
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 15s
Build and Push Docker Images / build-frontend (push) Successful in 59s
2026-03-25 08:02:24 +01:00
7dea2de7f3 Fix unit select
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 13s
Build and Push Docker Images / build-frontend (push) Successful in 58s
2026-03-23 14:11:40 +01:00
4db753d34a Fix Banking and Profiles
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 14s
Build and Push Docker Images / build-frontend (push) Successful in 59s
2026-03-23 08:29:54 +01:00
e0e99ba6f5 Fix #146 2026-03-23 08:26:21 +01:00
ace2213cc4 Fix #145 2026-03-23 08:16:44 +01:00
7e6c5cc189 Fix Changelog
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 21s
Build and Push Docker Images / build-frontend (push) Successful in 14s
2026-03-22 22:14:17 +01:00
7c644c941a fix #141
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 15s
Build and Push Docker Images / build-frontend (push) Successful in 57s
fix #142
2026-03-22 22:10:41 +01:00
11a242d70d 4. Zwischenstand
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 15s
Build and Push Docker Images / build-frontend (push) Successful in 1m0s
2026-03-22 17:43:41 +01:00
9f665fc3b8 3. Zwischenstand 2026-03-22 13:53:29 +01:00
03bcc1a939 2. Zwischenstand
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 15s
Build and Push Docker Images / build-frontend (push) Successful in 2m43s
2026-03-21 22:56:56 +01:00
68b2cbb0ee Zwischenstand 2026-03-21 22:13:19 +01:00
b009ac845f Start UI Change 2026-03-21 21:13:22 +01:00
cfd84b773f Revert "Added missing files"
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 15s
Build and Push Docker Images / build-frontend (push) Successful in 53s
This reverts commit 6c3c318f86.
2026-03-21 17:57:26 +01:00
8038f03406 Added missing files 2026-03-21 17:57:23 +01:00
6c3c318f86 Added missing files 2026-03-21 17:56:39 +01:00
8dfcffc92b Added Repository Changelog
Some checks failed
Build and Push Docker Images / build-backend (push) Successful in 27s
Build and Push Docker Images / build-frontend (push) Failing after 28s
2026-03-21 17:52:01 +01:00
9ecacdab50 Handlebars Util 2026-03-21 17:44:44 +01:00
44fb50b11e Removed non available Entries 2026-03-21 17:44:37 +01:00
23c4d21f44 Added UST Auswertung 2026-03-21 17:44:25 +01:00
6f77bccd85 DB Changes 2026-03-21 17:42:59 +01:00
be336a51ab Changes on Admin Interface 2026-03-21 17:10:03 +01:00
ac2e2fcfe9 Fix for no Files present in tenant 2026-03-21 17:09:38 +01:00
9dbb194c8a Fix False Open State for cancelled Invoices 2026-03-21 17:08:57 +01:00
0aacb18aaa Fix False Showing Card 2026-03-21 17:07:47 +01:00
e3a1636018 Fix #44 with Handlebars Templates 2026-03-21 17:05:04 +01:00
55bb2589a4 Fix Darkmode Dashboard
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 14s
Build and Push Docker Images / build-frontend (push) Successful in 52s
2026-03-18 18:47:02 +01:00
05d99e9e7d #133
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 20s
Build and Push Docker Images / build-frontend (push) Successful in 13s
2026-03-18 18:36:38 +01:00
7e0a2f5e4f New Admin Dashboard
Some checks failed
Build and Push Docker Images / build-backend (push) Failing after 25s
Build and Push Docker Images / build-frontend (push) Successful in 1m22s
2026-03-18 18:34:02 +01:00
84c174ca09 Rendering Fix 2026-03-18 18:33:47 +01:00
a9d3d0038f Card Changes for New Dashboard 2026-03-18 18:27:30 +01:00
003d88587a Fixed Dokubox and Sanitizing for File Uploads Fix #133 2026-03-18 18:27:14 +01:00
69ff646689 Selfhosting Readme 2026-03-18 18:26:39 +01:00
1511340f00 Neues Dashboard mit selbstwählbaren und verschiebbaren Cards 2026-03-18 18:26:30 +01:00
62accb5a86 Vorschläge System in Bankbuchungen 2026-03-17 18:14:09 +01:00
8c935c6101 Plantafel Reste 2026-03-17 18:12:42 +01:00
f6bdf2906f fix in invoiceprep 2026-03-17 18:12:20 +01:00
dff3a23c04 #131 2026-03-17 18:11:52 +01:00
966c121cbf #131
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 14s
Build and Push Docker Images / build-frontend (push) Successful in 51s
2026-03-17 18:11:45 +01:00
da50782ffc Fix #138
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 52s
2026-03-17 18:10:32 +01:00
6919de096a Fix #136
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 2m45s
Build and Push Docker Images / build-frontend (push) Successful in 57s
2026-03-17 15:34:06 +01:00
8892b36ae5 Fixes
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 2m55s
Build and Push Docker Images / build-frontend (push) Successful in 1m25s
2026-03-16 20:53:41 +01:00
8a08147265 Fixes 2026-03-16 20:46:26 +01:00
52c182cb5f Fixes
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 3m8s
Build and Push Docker Images / build-frontend (push) Successful in 1m15s
2026-03-04 20:44:19 +01:00
9cef3964e9 Serienrechnungen ausführung sowie Anwahl und liste 2026-03-04 19:54:12 +01:00
cf0fb724a2 Fix #126 2026-02-22 19:33:56 +01:00
bbb893dd6c Merge remote-tracking branch 'origin/dev' into dev
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 1m9s
2026-02-21 22:41:23 +01:00
724f152d70 Fix #116 2026-02-21 22:41:07 +01:00
27be8241bf Initial for #123 2026-02-21 22:23:32 +01:00
d27e437ba6 Fix Error in IcomingInvoice Opening of Drafts 2026-02-21 22:23:32 +01:00
f5253b29f4 Fix #113 2026-02-21 22:23:31 +01:00
0141a243ce Initial for #123
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 31s
Build and Push Docker Images / build-frontend (push) Successful in 1m10s
2026-02-21 22:21:10 +01:00
a0e1b8c0eb Fix Error in IcomingInvoice Opening of Drafts 2026-02-21 22:19:45 +01:00
45fb45845a Fix #116 2026-02-21 22:17:58 +01:00
409db82368 Mobile Dev
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 2m50s
Build and Push Docker Images / build-frontend (push) Successful in 1m13s
2026-02-21 21:21:39 +01:00
30d761f899 fix memberrlation 2026-02-21 21:21:27 +01:00
70636f6ac5 Fixed FinalInvoice
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 32s
Build and Push Docker Images / build-frontend (push) Successful in 1m9s
2026-02-20 09:20:55 +01:00
59392a723c Time Page 2026-02-19 18:33:24 +01:00
c782492ab5 Initial Mobile 2026-02-19 18:29:06 +01:00
844af30b18 Search und Save Function
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 33s
Build and Push Docker Images / build-frontend (push) Successful in 1m8s
2026-02-18 15:04:16 +01:00
6fded3993a New CustomerInventory,
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 32s
Build and Push Docker Images / build-frontend (push) Successful in 1m10s
New Mitgliederverwaltung für Vereine
New Bank Auto Complete
2026-02-17 12:38:39 +01:00
f26d6bd4f3 Load Fix
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 31s
Build and Push Docker Images / build-frontend (push) Successful in 16s
2026-02-16 13:56:45 +01:00
2621cc0d8d DB Fix
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 31s
Build and Push Docker Images / build-frontend (push) Successful in 15s
2026-02-16 12:57:29 +01:00
a8238dc9ba Added IBAN Saving, Automatic Saving, added Mitglieder
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 15s
Build and Push Docker Images / build-frontend (push) Successful in 1m11s
2026-02-16 12:43:52 +01:00
49d35f080d Added IBAN Saving, Automatic Saving, added Mitglieder
Some checks failed
Build and Push Docker Images / build-frontend (push) Has been cancelled
Build and Push Docker Images / build-backend (push) Has started running
2026-02-16 12:43:07 +01:00
189a52b3cd Added IBAN Saving, Automatic Saving, added Mitglieder
Some checks failed
Build and Push Docker Images / build-backend (push) Failing after 1m25s
Build and Push Docker Images / build-frontend (push) Failing after 38s
2026-02-16 12:40:07 +01:00
3f8ce5daf7 Tasks und Vertragstyp fix #17
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 30s
Build and Push Docker Images / build-frontend (push) Successful in 1m8s
2026-02-15 22:02:16 +01:00
087ba1126e Fix #105
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 1m9s
2026-02-15 20:50:52 +01:00
db4e9612a0 Logbuch Überarbeitung
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 29s
Build and Push Docker Images / build-frontend (push) Successful in 16s
2026-02-15 20:43:01 +01:00
cb4917c536 DB Restructuring 2026-02-15 13:30:19 +01:00
9f32eb5439 M2M Api 2026-02-15 13:29:26 +01:00
f596b46364 Missing Files
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 30s
Build and Push Docker Images / build-frontend (push) Successful in 1m6s
2026-02-15 13:25:23 +01:00
117da523d2 Fix #51 2026-02-15 13:25:14 +01:00
c2901dc0a9 Fix #89
Some checks failed
Build and Push Docker Images / build-backend (push) Failing after 31s
Build and Push Docker Images / build-frontend (push) Successful in 1m8s
2026-02-15 13:18:50 +01:00
8c2a8a7998 Fix #60
Some checks failed
Build and Push Docker Images / build-backend (push) Failing after 32s
Build and Push Docker Images / build-frontend (push) Has been cancelled
2026-02-15 13:17:56 +01:00
1dc74947f4 Fix #104
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 32s
Build and Push Docker Images / build-frontend (push) Successful in 1m13s
2026-02-15 12:52:34 +01:00
f63e793c88 Fix #90 2026-02-15 12:51:26 +01:00
29a84b899d Fix #92 2026-02-15 12:34:11 +01:00
be706a70f8 Incoming Invoice GPT Update 2026-02-15 12:31:03 +01:00
474b3e762c Updated Swagger 2026-02-14 20:11:17 +01:00
f793d4cce6 Supabase Removals Frontend
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 3m2s
Build and Push Docker Images / build-frontend (push) Successful in 3m38s
2026-02-14 13:35:21 +01:00
c3f46cd184 Supabase Removals Frontend 2026-02-14 13:15:01 +01:00
6bf336356d Supabase Removals Frontend 2026-02-14 13:14:22 +01:00
55699da42c Supabase Removals Frontend 2026-02-14 12:48:59 +01:00
053f184a33 Supabase Removals Backend 2026-02-14 12:29:59 +01:00
6541cb2adf Supabase Removals Backend 2026-02-14 12:27:44 +01:00
7dca84947e Supabase Removals 2026-02-14 12:16:50 +01:00
45fd6fda08 Remove Supa 2026-02-14 12:03:12 +01:00
31e80fb386 Fix #96 2026-02-14 11:59:07 +01:00
7ea28cc6c0 Neue E-Mail Sending Seite 2026-02-14 11:50:58 +01:00
c0faa398b8 Fix #103
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 33s
Build and Push Docker Images / build-frontend (push) Successful in 1m11s
2026-02-05 18:49:10 +01:00
19be1f0d03 Fix #102 2026-02-05 18:44:32 +01:00
c43d3225e3 Fix dev output #98 2026-02-05 18:30:39 +01:00
7125d15b3f PWA
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 3m56s
2026-02-04 16:33:13 +01:00
4b7cf171c8 PWA
Some checks failed
Build and Push Docker Images / build-backend (push) Successful in 31s
Build and Push Docker Images / build-frontend (push) Failing after 20s
2026-02-04 16:02:47 +01:00
59fdedfaa0 Fix for Rendering in Bank Booking
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 18s
Build and Push Docker Images / build-frontend (push) Successful in 1m7s
2026-02-02 18:03:41 +01:00
71d249d8bf #15
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 1m9s
2026-01-30 16:49:40 +01:00
e496a62b36 Fix for #74 and #72
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 1m7s
2026-01-30 16:36:58 +01:00
0bfef0806b Fix for #73
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 1m7s
2026-01-30 16:23:57 +01:00
5c69388f1c Fix for #2
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 1m7s
2026-01-30 16:20:03 +01:00
7ed0388acb Fix for #34
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 19s
Build and Push Docker Images / build-frontend (push) Successful in 1m8s
2026-01-30 16:15:31 +01:00
3aa0c7d77a Change for #34 2026-01-30 16:12:55 +01:00
77aa277347 Fix for Times Edit
Some checks failed
Build and Push Docker Images / build-backend (push) Successful in 3m7s
Build and Push Docker Images / build-frontend (push) Has been cancelled
2026-01-30 16:11:30 +01:00
2fff1ca8a8 Added Entity Wiki
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 32s
Build and Push Docker Images / build-frontend (push) Successful in 3m27s
2026-01-27 15:17:37 +01:00
e58929d9a0 Added Entity Wiki 2026-01-27 15:01:56 +01:00
90560ecd2c Added Internal Links #84 2026-01-27 14:07:36 +01:00
b07953fb7d Fix Cursor, Fix Task Item #87
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 1m5s
2026-01-27 13:07:40 +01:00
01ef3c5a42 Change for Agrar
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 31s
Build and Push Docker Images / build-frontend (push) Successful in 1m8s
2026-01-27 08:58:44 +01:00
2aed851224 Change for Agrar
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 32s
Build and Push Docker Images / build-frontend (push) Successful in 1m10s
2026-01-26 22:04:27 +01:00
c56fcfbd14 #84
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 33s
Build and Push Docker Images / build-frontend (push) Successful in 3m25s
2026-01-26 21:52:24 +01:00
ca2020b9c6 Added more text functions 2026-01-26 21:11:16 +01:00
c87212d54a Folders in Wiki 2026-01-26 20:43:35 +01:00
db22d47900 Changes More Functions to wiki 2026-01-26 20:31:17 +01:00
143485e107 Changes More Functions to wiki 2026-01-26 20:18:33 +01:00
c1d4b24418 Added Wiki 2026-01-26 19:44:08 +01:00
9655d4fa05 Fix Ownaccount Booking
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 1m9s
2026-01-22 19:45:30 +01:00
4efe452f1c Redone Layouts
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 30s
Build and Push Docker Images / build-frontend (push) Successful in 1m8s
2026-01-22 19:38:09 +01:00
cb21a85736 Added Dokubox Sync Service and Button Fix #12 2026-01-22 19:35:45 +01:00
e7554fa2cc .gitea/ISSUE_TEMPLATE/feature_request.md aktualisiert
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 16s
2026-01-22 17:42:28 +00:00
7c1fabf58a .gitea/ISSUE_TEMPLATE/bug_report.md aktualisiert
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 16s
2026-01-22 17:40:58 +00:00
d2b70e5883 Added Dokubox Sync Service and Button Fix #12
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 30s
Build and Push Docker Images / build-frontend (push) Successful in 1m10s
2026-01-22 17:05:22 +01:00
1a065b649c Fixed #71
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 1m10s
2026-01-22 14:48:35 +01:00
34c58c3755 Fixed #71
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 1m7s
2026-01-22 11:28:39 +01:00
37d8a414d3 Fixed DB
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 30s
Build and Push Docker Images / build-frontend (push) Successful in 15s
2026-01-21 15:16:23 +01:00
7f4f232c32 Added Health Ednpoint for Devices
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 31s
Build and Push Docker Images / build-frontend (push) Successful in 17s
Added Offline Sync for times
2026-01-21 12:38:36 +01:00
d6f257bcc6 Fix für #71
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 1m8s
2026-01-21 10:52:56 +01:00
3109f4d5ff Fix for Object Create from Customer
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 1m8s
2026-01-20 16:16:08 +01:00
235b33ae08 Fix for #46
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 1m11s
2026-01-20 15:16:47 +01:00
2d135b7068 Fix for #65
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 1m10s
2026-01-20 15:08:58 +01:00
8831320a4c Fix ts
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 2m2s
Build and Push Docker Images / build-frontend (push) Successful in 16s
2026-01-20 14:14:58 +01:00
000d409e4d fix for no createddocuments
Some checks failed
Build and Push Docker Images / build-backend (push) Failing after 31s
Build and Push Docker Images / build-frontend (push) Has been cancelled
2026-01-20 14:14:09 +01:00
160124a184 fix for #68
Some checks failed
Build and Push Docker Images / build-backend (push) Failing after 1m28s
Build and Push Docker Images / build-frontend (push) Successful in 1m12s
2026-01-20 13:55:10 +01:00
26dad422ec added size column 2026-01-17 16:04:39 +01:00
e59cbade53 Webdav 2026-01-17 16:04:32 +01:00
6423886930 added webdav server 2026-01-17 15:15:34 +01:00
6adf09faa0 DB Change con string 2026-01-17 15:15:26 +01:00
d7f3920763 Cors Change 2026-01-17 15:15:06 +01:00
3af92ebf71 #16 Added Move Up 2026-01-17 12:55:39 +01:00
5ab90830a0 Redone Files Index, #16 Added Drag and Drop for Files 2026-01-17 12:36:28 +01:00
4f72919269 #64 Fix
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 1m8s
2026-01-16 13:14:09 +01:00
f2c9dcc900 #64 Fix
Some checks failed
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Failing after 35s
2026-01-16 13:11:54 +01:00
b4ec792cc0 Diasbled Label Test Card
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 1m7s
2026-01-15 19:09:26 +01:00
9b3f48defe Added Calculator 2026-01-15 19:08:26 +01:00
5edc90bd4d Fix #8
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 1m8s
2026-01-15 18:45:35 +01:00
d140251aa0 Fix #7 Added Month Markings, Range Select 2026-01-15 18:45:25 +01:00
e7fb2df5c7 Added Debouncing #36
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 1m8s
2026-01-15 18:19:05 +01:00
f27fd3f6da Fix TS
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 29s
Build and Push Docker Images / build-frontend (push) Successful in 15s
2026-01-15 18:07:58 +01:00
d3e2b106af Storno Fix createddocument link. Added Disable and Tooltip for Storno Button
Some checks failed
Build and Push Docker Images / build-backend (push) Failing after 29s
Build and Push Docker Images / build-frontend (push) Successful in 1m8s
2026-01-15 18:05:44 +01:00
769d2059ca Redone Search to inluce more Columns #36
TODO: Spalten nachpflegen
2026-01-15 18:05:14 +01:00
53349fae83 Fix Link Buttons Added New link buttons
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 1m7s
2026-01-15 13:38:01 +01:00
d8eb1559c8 Update Problem bei #54
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 31s
Build and Push Docker Images / build-frontend (push) Successful in 16s
2026-01-15 13:18:58 +01:00
1203b6cbd1 .gitea/ISSUE_TEMPLATE/bug_report.md aktualisiert
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 16s
2026-01-15 11:39:03 +00:00
525f2906fb .gitea/ISSUE_TEMPLATE/feature_request.md aktualisiert
Some checks failed
Build and Push Docker Images / build-frontend (push) Has been cancelled
Build and Push Docker Images / build-backend (push) Has been cancelled
2026-01-15 11:38:50 +00:00
b105382abf .gitea/ISSUE_TEMPLATE/bug_report.md aktualisiert
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 15s
2026-01-15 11:38:00 +00:00
b1cdec7d17 Merge pull request 'Added feature request template' (#62) from dev into main
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 16s
Reviewed-on: #62
2026-01-15 11:31:57 +00:00
6b9de04d83 Added feature request template
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 15s
Build and Push Docker Images / build-frontend (push) Successful in 16s
2026-01-15 12:30:33 +01:00
f1d512b2e5 Merge pull request 'dev' (#61) from dev into main
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 16s
Reviewed-on: #61
2026-01-15 11:29:15 +00:00
529ec0c77d Added bug report template
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 31s
Build and Push Docker Images / build-frontend (push) Successful in 15s
2026-01-15 12:27:56 +01:00
246677b750 Fixed Missing Phase on Init 2026-01-15 12:19:34 +01:00
c839714945 Fixed Failing Load #58
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 1m10s
2026-01-15 12:14:46 +01:00
8614917a05 Optimized Dockerfile for Frontend
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 19s
Build and Push Docker Images / build-frontend (push) Successful in 3m12s
2026-01-15 12:03:40 +01:00
2de80ea6ca Fixed #59
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 3m1s
Build and Push Docker Images / build-frontend (push) Successful in 5m49s
2026-01-15 11:52:07 +01:00
6f5fed0ffb Fixed Date #30
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 33s
Build and Push Docker Images / build-frontend (push) Successful in 5m54s
2026-01-14 15:51:04 +01:00
767152c535 Added Color Mode Button Fix #46
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 5m52s
2026-01-14 15:15:36 +01:00
3128893ba2 Added Error Toasts Fix #52
Some checks failed
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Has been cancelled
2026-01-14 15:10:37 +01:00
bcf460cfd5 Fix mtoLoad Customer in Contracts #56
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 31s
Build and Push Docker Images / build-frontend (push) Successful in 15s
2026-01-14 11:15:32 +01:00
da704be925 Fix DeliveryDateType #23 #54
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 35s
Build and Push Docker Images / build-frontend (push) Successful in 17s
2026-01-14 11:06:48 +01:00
c049730599 Merge remote-tracking branch 'origin/dev' into dev
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 18s
Build and Push Docker Images / build-frontend (push) Successful in 2m19s
2026-01-13 14:41:34 +01:00
0194345ed8 Renamed Anwesenheiten to Zeiten FIX #31 2026-01-13 14:41:21 +01:00
82d8cd36b9 Renamed Anwesenheiten to Zeiten FIX#31
Some checks failed
Build and Push Docker Images / build-backend (push) Successful in 19s
Build and Push Docker Images / build-frontend (push) Has been cancelled
2026-01-13 14:40:53 +01:00
66110da6c4 Removed Dev Output
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 5m53s
2026-01-13 14:24:39 +01:00
267648074c Fix #53
Some checks failed
Build and Push Docker Images / build-backend (push) Successful in 33s
Build and Push Docker Images / build-frontend (push) Has been cancelled
2026-01-13 14:24:04 +01:00
32b4c40e11 Fix #1
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 5m55s
2026-01-12 19:40:32 +01:00
f044195d86 Fix #20 2026-01-12 19:37:22 +01:00
202e20ddd5 Fix #3
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 34s
Build and Push Docker Images / build-frontend (push) Successful in 16s
2026-01-12 19:27:46 +01:00
905f2e7bf4 Fix #47
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 18s
Build and Push Docker Images / build-frontend (push) Successful in 6m2s
Fix #19
Fix Adresse laden bei Dokument kopieren
2026-01-12 18:33:08 +01:00
b39a52fb20 Fix #19 Ansprechpartner nicht auswählbar
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 18s
Build and Push Docker Images / build-frontend (push) Successful in 5m58s
2026-01-11 11:03:11 +01:00
098bd02808 Fixed PageLeaveGuard.vue Dark Mode
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 18s
Build and Push Docker Images / build-frontend (push) Successful in 6m9s
2026-01-10 20:03:45 +01:00
b35c991634 Fixed PageLeaveGuard.vue Dark Mode
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 5m52s
2026-01-10 19:49:28 +01:00
dc376894be Fixed LabelPrinter Dark Mode 2026-01-10 19:46:16 +01:00
90788f22da Fixed displayOpenBalances.vue 2026-01-10 19:43:09 +01:00
d901ebe365 Fix #41
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 17s
Build and Push Docker Images / build-frontend (push) Successful in 5m56s
Redesign Textvorlagen
2026-01-10 19:01:40 +01:00
7f6ba99328 Added Schnellauswahl für die Exporte
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 5m57s
2026-01-10 18:00:12 +01:00
8afdf06c8e Fixed TS #39
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 29s
Build and Push Docker Images / build-frontend (push) Successful in 16s
2026-01-10 17:38:59 +01:00
e1205a8de5 Fixed DATEV Export #39
Some checks failed
Build and Push Docker Images / build-backend (push) Failing after 30s
Build and Push Docker Images / build-frontend (push) Successful in 15s
2026-01-10 17:34:02 +01:00
08da93b6c3 Fixed DATEV Export #39
Some checks failed
Build and Push Docker Images / build-backend (push) Failing after 31s
Build and Push Docker Images / build-frontend (push) Successful in 16s
2026-01-10 17:30:02 +01:00
b0ace924d4 Fix Total Amount #37
Some checks failed
Build and Push Docker Images / build-backend (push) Successful in 18s
Build and Push Docker Images / build-frontend (push) Has been cancelled
2026-01-10 17:25:12 +01:00
593118c181 Changed Reamdme
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 15s
2026-01-08 23:23:13 +01:00
db21b43120 Merge pull request 'dev' (#40) from dev into main
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 18s
Build and Push Docker Images / build-frontend (push) Successful in 16s
Reviewed-on: #40
2026-01-08 22:21:06 +00:00
67d2a05ac4 #37 open for testing
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 6m17s
2026-01-08 22:54:55 +01:00
b95d539907 Fix Search and Option Display #38 2026-01-08 22:51:18 +01:00
76b363fdaf fix #29 Corrected User ID
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 33s
Build and Push Docker Images / build-frontend (push) Successful in 16s
2026-01-08 12:26:13 +01:00
2cb0d9b607 Fixed Workflow API URL
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 5m55s
2026-01-08 11:28:56 +01:00
037a10e93e Fixed DB
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 30s
Build and Push Docker Images / build-frontend (push) Successful in 16s
2026-01-08 11:17:51 +01:00
c36b9aa872 Fixed DB
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 29s
Build and Push Docker Images / build-frontend (push) Successful in 15s
2026-01-08 11:13:29 +01:00
14a9435a5a Fixed DB
Some checks failed
Build and Push Docker Images / build-backend (push) Failing after 28s
Build and Push Docker Images / build-frontend (push) Successful in 15s
2026-01-08 11:11:57 +01:00
8126c2d3f4 Fixed DB
Some checks failed
Build and Push Docker Images / build-backend (push) Failing after 28s
Build and Push Docker Images / build-frontend (push) Successful in 15s
2026-01-08 11:10:02 +01:00
a892b7a6e4 Fixed DB
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 34s
Build and Push Docker Images / build-frontend (push) Successful in 16s
2026-01-08 10:55:48 +01:00
be7b219569 Merge remote-tracking branch 'origin/dev' into dev
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Successful in 2m17s
2026-01-06 21:13:04 +01:00
998d725528 Fixed Login
Allowed Workflows to be public #22
2026-01-06 21:12:51 +01:00
17cd3dc3a3 Fixed Login
Some checks failed
Build and Push Docker Images / build-backend (push) Successful in 16s
Build and Push Docker Images / build-frontend (push) Has been cancelled
Allowed Workflows to be public
2026-01-06 21:12:05 +01:00
1d9488b64d Removed Alert Message
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 35s
Build and Push Docker Images / build-frontend (push) Successful in 5m33s
2026-01-06 15:21:09 +01:00
9fb520d8c3 Removed Capacitor 2026-01-06 15:20:26 +01:00
3bcfacdf84 Added Workflow
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 4m34s
Build and Push Docker Images / build-frontend (push) Successful in 10m32s
2026-01-06 12:12:34 +01:00
8ea41802dd Tidying 2026-01-06 12:12:25 +01:00
af5bd12577 Added Frontend 2026-01-06 12:09:31 +01:00
6f3d4c0bff Added Backend 2026-01-06 12:07:43 +01:00
125c16a20c Merge branch 'beta' into 'main'
Beta

See merge request fedeo/software!60
2026-01-06 11:06:07 +00:00
d01bd7fc0c Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!59
2026-01-06 11:02:25 +00:00
d3fc2e6ad3 LabelPrinter Implementation 2026-01-06 11:58:29 +01:00
c1ed8cd028 Try for SEPA 2026-01-06 11:58:19 +01:00
786ac06e09 Fix SyncedAt Display 2026-01-06 11:57:33 +01:00
a00fd6d51f Added Workflows 2026-01-06 11:57:00 +01:00
c439396595 Fix for deliveryNotes 2026-01-06 11:56:35 +01:00
b013ef8f4b Merge Backend in FEDEO MONO 2026-01-06 11:54:19 +01:00
7c3968636d Merge branch 'orm' into 'main'
Orm

See merge request fedeo/backend!18
2026-01-06 10:45:43 +00:00
bf3f0cc784 Added Public Links 2026-01-06 11:43:51 +01:00
7f09ef2911 Added Dokubox Service & Mailparser 2026-01-06 11:43:43 +01:00
8b9b5744bf Fix Time Issue 2026-01-06 11:43:19 +01:00
fa369f7b81 Added Public Pin Header to Cors 2026-01-06 11:41:34 +01:00
5485d2c0cc Fix Synced At 2026-01-06 11:41:13 +01:00
c1ff4d1a08 Merge branch 'orm' into 'main'
Orm

See merge request fedeo/backend!17
2026-01-02 13:35:59 +00:00
8a2e91e702 TS Fix 2026-01-02 14:34:53 +01:00
65acad1c0d Added Prepare Service 2026-01-02 12:45:47 +01:00
bc3b944f5d Added Prepare Service 2026-01-02 12:45:24 +01:00
e8fe6940c2 Added Prepare Service 2026-01-02 12:45:14 +01:00
7df88ef5e4 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!58
2026-01-02 11:44:48 +00:00
8a87113275 Added Prepare Service 2026-01-02 12:44:26 +01:00
94ed9ac343 Added Preparing 2026-01-02 12:39:47 +01:00
848c9e4b2f Added Prepare Service 2026-01-02 12:39:20 +01:00
b26c9432f1 Added Payment Type to list 2026-01-02 12:13:11 +01:00
3c573380a8 Merge branch 'orm' into 'main'
Orm

See merge request fedeo/backend!16
2026-01-01 15:39:55 +00:00
a5f82c3ef3 Fix TS 2026-01-01 16:37:40 +01:00
78ae8989ba Fix TS 2026-01-01 16:35:43 +01:00
cebe20fd43 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!57
2026-01-01 15:28:02 +00:00
3da3aee50d Fixed Dates in create resource 2026-01-01 16:24:26 +01:00
2c7449ef7a Added Leave Guard 2026-01-01 16:24:00 +01:00
fb746b4d59 Statement Sync 2026-01-01 15:52:05 +01:00
b3fd5eafbc Bankstatementsync 2026-01-01 15:51:47 +01:00
4121666c70 Serial and Other 2026-01-01 15:34:35 +01:00
a3df87caee Serial and Other 2026-01-01 15:33:48 +01:00
8db4ad2203 Changes 2026-01-01 15:31:38 +01:00
0d1b4b7eb8 Added Page Leave Guard 2026-01-01 15:30:06 +01:00
e0f73c20c9 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!56
2025-12-28 13:53:52 +00:00
3e5c6ca8da Fix 2025-12-28 14:49:51 +01:00
bffc5666fe Fix 2025-12-28 14:39:54 +01:00
7d7689999e Merge branch 'orm' into 'main'
Change in Resource

See merge request fedeo/backend!15
2025-12-28 13:32:11 +00:00
fb52f88ec3 Merge branch 'beta' into 'main'
Beta

See merge request fedeo/software!55
2025-12-27 13:06:20 +00:00
902e3ac59a Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!54
2025-12-27 12:07:48 +00:00
97f66f808a Change in Resource 2025-12-27 13:05:01 +01:00
240264aafb Fix Serialinvoice table 2025-12-27 13:04:02 +01:00
d5999bfb20 Fix 2025-12-27 12:56:54 +01:00
bded9189e3 Merge branch 'orm' into 'main'
Changed Resource Config

See merge request fedeo/backend!14
2025-12-19 08:39:47 +00:00
282d1eb052 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!53
2025-12-19 08:39:20 +00:00
7d4adbb3e4 Fix Service Saving 2025-12-18 12:45:49 +01:00
8e9b9dfc98 Changed Resource Config 2025-12-18 12:19:09 +01:00
bb1e73443b Fixed Banking Page 2025-12-18 12:18:57 +01:00
2b12e6ada7 Merge branch 'orm' into 'main'
Fix E-Mail

See merge request fedeo/backend!13
2025-12-17 13:36:02 +00:00
1ae640dc02 Merge branch 'devCorrected' into 'beta'
Fix E-Mail

See merge request fedeo/software!52
2025-12-17 13:35:37 +00:00
9d6f2de4ab Fix E-Mail 2025-12-17 09:23:25 +01:00
280cf4518a Fix E-Mail 2025-12-17 09:23:07 +01:00
439ec3438d Merge branch 'devCorrected' into 'beta'
Time Changes

See merge request fedeo/software!51
2025-12-17 07:30:58 +00:00
049a5b2264 packages changes 2025-12-16 16:28:10 +01:00
5aac81f601 Time Changes 2025-12-16 16:27:17 +01:00
6053b7340f Time Changes 2025-12-16 16:27:04 +01:00
8e1a28577c Merge branch 'orm' into 'main'
Time

See merge request fedeo/backend!12
2025-12-16 15:25:43 +00:00
e6bc123481 Time 2025-12-16 16:23:25 +01:00
6d8193296e Time Changes 2025-12-16 16:23:12 +01:00
6ded3b859f Merge branch 'orm' into 'main'
Orm

See merge request fedeo/backend!11
2025-12-16 13:14:49 +00:00
94c252ec6c rfid 2025-12-16 14:13:48 +01:00
9a0a757757 Merge branch 'devCorrected' into 'beta'
Fixed Times

See merge request fedeo/software!50
2025-12-14 16:20:33 +00:00
780b899d42 Fixed Times 2025-12-14 17:15:24 +01:00
5270313b3d Time Migration 2025-12-14 17:14:50 +01:00
1281976ec3 Time Migration 2025-12-14 16:29:08 +01:00
267a57c4ea Time Migration 2025-12-14 16:29:00 +01:00
e5c3863eee Schema Migrations 2025-12-14 16:28:30 +01:00
c8f85496ce Merge branch 'devCorrected' into 'beta'
Fixed linkedDocuments Agrar

See merge request fedeo/software!49
2025-12-13 13:04:17 +00:00
9ddda1a933 Fixed linkedDocuments Agrar 2025-12-13 14:00:14 +01:00
ca393d1625 Merge branch 'devCorrected' into 'beta'
Fix for Invoice Gen

See merge request fedeo/software!48
2025-12-10 14:06:06 +00:00
d916ed471b Fix for Invoice Gen 2025-12-10 14:49:40 +01:00
3d51a1aa6d Merge branch 'devCorrected' into 'beta'
Fix for Copying

See merge request fedeo/software!47
2025-12-10 11:44:25 +00:00
3328279581 Fix for Copying 2025-12-10 12:40:34 +01:00
053f3ce557 Merge branch 'orm' into 'main'
Fixed Put

See merge request fedeo/backend!9
2025-12-10 11:35:37 +00:00
6d936c4be7 Fixed Put 2025-12-10 12:31:10 +01:00
d210eb857f Merge branch 'devCorrected' into 'beta'
Fix for Copying

See merge request fedeo/software!46
2025-12-10 11:27:24 +00:00
1e0f18c854 Fix for Copying 2025-12-10 12:23:41 +01:00
9263c24ede Merge branch 'orm' into 'main'
Added Plants to resource config

See merge request fedeo/backend!8
2025-12-10 09:29:42 +00:00
3f7f8a4498 Added Plants to resource config 2025-12-10 10:28:53 +01:00
1ab124ac7a Merge branch 'devCorrected' into 'beta'
Fix for Copying

See merge request fedeo/software!45
2025-12-10 07:43:41 +00:00
65da63d1c8 Merge branch 'orm' into 'main'
Orm

See merge request fedeo/backend!7
2025-12-10 07:40:46 +00:00
eeceb4a8f6 Fix for Copying 2025-12-10 08:39:51 +01:00
58836fb0ef Redone 2025-12-10 08:39:44 +01:00
4016c8b6b5 Redone 2025-12-10 08:32:22 +01:00
ab2b5135c0 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!44
2025-12-10 07:25:44 +00:00
ac2ed79e10 Fix for Copying 2025-12-10 08:21:59 +01:00
7ce5616e65 Fix for Copying 2025-12-09 16:00:01 +01:00
aefd8ffba4 Merge branch 'orm' into 'main'
Orm

See merge request fedeo/backend!6
2025-12-09 11:27:54 +00:00
c3467bdd9d Redone 2025-12-09 12:27:20 +01:00
641130e506 Redone 2025-12-09 12:26:18 +01:00
6d05001812 Tidying 2025-12-09 12:26:10 +01:00
4a3515f6f3 Schema and Config Changes 2025-12-09 12:12:05 +01:00
b88e840ff5 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!43
2025-12-09 11:11:42 +00:00
84c88ef69e Added Buttons for all connected Documents 2025-12-09 12:07:00 +01:00
8b70b77b85 Added Buttons for all connected Documents 2025-12-09 11:41:21 +01:00
76941abbf2 BETA for new DB 2025-12-09 11:36:12 +01:00
a161306359 BETA for new DB 2025-12-09 11:05:56 +01:00
8a528f0711 Merge branch 'devCorrected' into 'beta'
BETA for new DB

See merge request fedeo/software!41
2025-12-09 07:35:57 +00:00
6c1f95db9f Merge branch 'orm' into 'main'
fix laoding issue

See merge request fedeo/backend!5
2025-12-09 07:35:27 +00:00
861984e4b1 fix laoding issue
fix missing mtm
2025-12-09 08:29:24 +01:00
c6354ac656 BETA for new DB 2025-12-09 08:28:41 +01:00
0c1287d3b9 Fix NumberRange 2025-12-09 08:17:52 +01:00
862912cd66 Merge branch 'orm' into 'main'
Redone

See merge request fedeo/backend!4
2025-12-08 19:25:30 +00:00
a605fdc351 Redone 2025-12-08 20:23:59 +01:00
d234a2371b Merge branch 'beta' into 'main'
2025.21.0

See merge request fedeo/software!40
2025-12-08 16:14:48 +00:00
183fefb557 Merge branch 'devCorrected' into 'beta'
BETA for new DB

See merge request fedeo/software!39
2025-12-08 14:15:32 +00:00
64b3ec626c docker-compose.yml bearbeiten 2025-12-08 14:11:25 +00:00
fd52cadbff Merge branch 'orm' into 'main'
Orm

See merge request fedeo/backend!3
2025-12-08 14:09:37 +00:00
b694340f38 Redone 2025-12-08 15:09:15 +01:00
888336dd04 BETA for new DB 2025-12-08 14:40:21 +01:00
e35e857380 Redone 2025-12-08 12:27:28 +01:00
c1120d1878 Schema Changes 2025-12-08 12:15:27 +01:00
428a002e9f Redone 2025-12-08 12:15:20 +01:00
1d3bf94b88 Route Changes 2025-12-08 11:45:50 +01:00
8f0efc0d72 schema changes 2025-12-08 11:45:37 +01:00
e760bd5f97 tsconfig.json 2025-12-07 23:30:33 +01:00
899f8dce20 tsconfig.json 2025-12-07 23:28:36 +01:00
aa1f3b1cb3 tsconfig.json 2025-12-07 23:23:18 +01:00
f5825f9a18 tsconfig.json 2025-12-07 23:14:31 +01:00
607024c813 Changed Dockerfile 2025-12-07 23:06:29 +01:00
206bdc6392 docker-compose.yml bearbeiten 2025-12-07 22:03:06 +00:00
eda8d357da Merge branch 'orm' into 'main'
Orm

See merge request fedeo/backend!2
2025-12-07 21:49:31 +00:00
32b46f58a4 TS fixes 2025-12-07 22:45:49 +01:00
e92eccc7d3 TS fixes 2025-12-07 22:45:02 +01:00
af5f9567f1 TS fixes 2025-12-07 22:43:01 +01:00
8faaef1ef5 TS fixes 2025-12-07 22:42:23 +01:00
d33b908775 TS fixes 2025-12-07 22:40:15 +01:00
5968329c8f package changes 2025-12-07 22:34:48 +01:00
09d67a7522 redone routes 2025-12-07 22:27:57 +01:00
0b32b69d10 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!38
2025-12-07 21:22:02 +00:00
9bfb880f7b BETA for new DB 2025-12-07 22:17:57 +01:00
b90e056e7c redone routes 2025-12-07 22:06:37 +01:00
dc0b49355d db changes 2025-12-07 22:06:26 +01:00
76e40cd9e1 db changes 2025-12-07 17:11:26 +01:00
0f3c8c862f removed Routes, Introduced Single Route with Cecking 2025-12-06 22:50:15 +01:00
dff2b05401 Redone Routes customers,contracts,contacts,vendors 2025-12-06 20:33:27 +01:00
765f3c42c1 Added dbSearch util 2025-12-06 20:31:59 +01:00
1e71e54314 Schema 2025-12-06 20:10:57 +01:00
d895583ea2 Converted Routes 2025-12-06 19:29:47 +01:00
7450f90a0f Schema Changes 2025-12-06 19:29:28 +01:00
63af22b671 Introduced New DB 2025-12-06 10:34:58 +01:00
407592680a Open Changes 2025-12-05 11:49:33 +01:00
d6badafeb9 Added Health Endpoint 2025-11-30 15:08:18 +01:00
d408dadd88 Added Health Endpoint 2025-11-30 15:04:47 +01:00
253b04ec0d Added Download Option for Drafts/Base64 2025-11-30 13:37:38 +01:00
de2692f704 Mobile 2025-11-30 13:37:19 +01:00
665f0d1454 Added NoControls Option 2025-11-20 12:38:49 +01:00
24f576aeaa Remodel for Mobile 2025-11-20 12:38:38 +01:00
f8c62a90f0 PDF Time Eval Corrections 2025-11-14 20:13:54 +01:00
951011bc0e Merge branch 'devCorrected' into 'beta'
Introduced Employee Number

See merge request fedeo/software!37
2025-11-14 19:01:20 +00:00
5fd683eacc Merge branch 'beta' into 'main'
2025.20.1

See merge request fedeo/software!36
2025-11-14 19:00:37 +00:00
5f6df7c69d Fixed Some Errors in IncomingInvoices 2025-11-14 17:54:27 +01:00
da074df63c Redone IncomingInvoice Show/Edit 2025-11-14 17:48:15 +01:00
32c71fe49b Introduced Employee Number
Added Ability to Save Bericht
2025-11-14 17:34:15 +01:00
c4d0a20bbc Added dataUriToFile Function 2025-11-14 17:33:41 +01:00
263f389e91 Removed Download Button for Temporary Display 2025-11-14 17:33:27 +01:00
24e80a6a0a Added Pagebreak Error 2025-11-11 19:36:38 +01:00
e0638b5a98 Merge branch 'devCorrected' into 'beta'
Fixed Phase Change

See merge request fedeo/software!35
2025-11-11 08:00:28 +00:00
57abbe8534 Fixed Phase Change
Fixed Evaluate Date
2025-11-11 08:56:52 +01:00
f61c780185 Fixed not included last day 2025-11-11 08:52:00 +01:00
48263b28b5 Fixed Search Speed 2025-11-11 08:36:34 +01:00
7cd9a3e074 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!34
2025-11-10 14:05:48 +00:00
914c7e4fc1 Fixed Dumb Error 2025-11-10 14:40:13 +01:00
94aee4540a Fixed Filters 2025-11-10 13:57:57 +01:00
aaf61760a3 Fixed No Category Error 2025-11-10 13:57:45 +01:00
8a88c6878e Fixed RecreationDays Compensation 2025-11-10 13:50:30 +01:00
4f01d2407b Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!33
2025-11-10 11:14:31 +00:00
d6dd0a1602 Fixed loading 2025-11-10 12:06:34 +01:00
c1dc88cdd9 Fixed Search 2025-11-10 12:03:43 +01:00
1beb0dbaf3 Tidying 2025-11-10 11:44:27 +01:00
de32d72eda Allowed Filters to stay Persistent, Introduced Extra Column for ActivePhase 2025-11-10 11:42:20 +01:00
87aaa28d92 Redone Submit/approve Process 2025-11-10 11:07:11 +01:00
70347920f2 Merge branch 'beta' into 'main'
Beta

See merge request fedeo/software!32
2025-11-09 19:31:52 +00:00
2f177ad603 Merge branch 'devCorrected' into 'beta'
Changed Auth

See merge request fedeo/software!31
2025-11-09 19:28:08 +00:00
06b97cbdae Changed Auth 2025-11-09 19:51:32 +01:00
2382b2dfae Fixed Role Loading 2025-11-09 18:52:44 +01:00
fc3ed1fb11 Fixed Tenant Error 2025-11-09 18:49:30 +01:00
29cfaccd02 Fixes 2025-11-09 18:47:30 +01:00
d6e11766da Merge branch 'devCorrected' into 'beta'
Changed DC

See merge request fedeo/software!30
2025-11-09 17:42:29 +00:00
3cd7120b4b Changed DC 2025-11-09 18:38:31 +01:00
433bb7d05e Merge branch 'devCorrected' into 'beta'
Fix Auth

See merge request fedeo/software!29
2025-11-09 17:31:32 +00:00
65598bceac Fix Auth 2025-11-09 18:27:09 +01:00
67389a5f78 Merge branch 'beta' into 'main'
2025.20.0

See merge request fedeo/software!28
2025-11-09 17:10:06 +00:00
0909f34649 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!27
2025-11-09 17:04:53 +00:00
4cfa4dbffd Fixed Scroll in EntityShowSub.vue 2025-11-09 17:57:58 +01:00
f3892861b1 Removed Abwesenheiten 2025-11-09 17:53:29 +01:00
572d564135 TS Fixes 2025-11-09 16:12:18 +01:00
7eb4a32552 Redone Update Modal 2025-11-09 16:06:45 +01:00
9d2cecd55b Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!26
2025-11-09 14:53:54 +00:00
16962a6df8 Changed Node Version 2025-11-09 15:48:30 +01:00
cf2b88199a Removed Module Chatwoot 2025-11-09 15:37:37 +01:00
75e2f84726 Redone Auth 2025-11-08 19:02:08 +01:00
8b34609e53 Added GoCardless Secrets 2025-11-08 19:01:52 +01:00
d7939a9ca4 New Staff Functions 2025-11-08 19:01:22 +01:00
ee8e17d80e Index Registers 2025-11-08 19:00:46 +01:00
29bebe6149 Functions Time Eval and PDF 2025-11-08 18:59:47 +01:00
6d0b764ee2 Introduced Dayjs as Server Plugin 2025-11-08 18:59:25 +01:00
89abbde753 Fixed Datev Export 2025-11-08 18:59:10 +01:00
61d22dbfa1 Added GoCardless Generation 2025-11-08 18:58:54 +01:00
62146ff970 Tidying 2025-11-08 18:57:28 +01:00
802c0c3f09 Tidying 2025-11-08 18:57:22 +01:00
d54a3aab7a Tidying, Zip Check 2025-11-08 18:57:09 +01:00
6d22aec2f4 Tidying 2025-11-08 18:56:41 +01:00
86a5b7e63e Added Location Prop 2025-11-08 18:56:33 +01:00
3a0c0fc9a7 Added Tempstore Saving 2025-11-08 18:56:21 +01:00
10b29c336a PDF Viewer Location 2025-11-08 18:55:46 +01:00
e4ae514830 Tidying and PDF Viewer Location 2025-11-08 18:55:35 +01:00
d9f35602b2 Introduced Helpdesk 2025-11-08 18:54:52 +01:00
1838d07082 Fixed Some Functions 2025-11-08 18:54:31 +01:00
655601dddb Time Composable 2025-11-08 18:53:56 +01:00
3ac8b63164 Redone Banksettings 2025-11-08 18:53:48 +01:00
43a6d1d631 Added Location to PDF Viewer in EVal 2025-11-08 18:52:25 +01:00
1526879a38 MainNav Links Times/Profiles 2025-11-08 18:50:06 +01:00
157533bb9d Added Dayjs Plugin 2025-11-08 18:49:31 +01:00
cf31d43702 Redone Times 2025-11-08 18:49:21 +01:00
26b7dfc06c Redone Profiles Edit 2025-11-08 18:47:46 +01:00
61835c3f26 Fixed TS Errors 2025-10-31 16:45:27 +01:00
55c101df12 Fixed TS Errors 2025-10-31 16:39:49 +01:00
c439eec66c Added Notifications Basics 2025-10-31 16:29:36 +01:00
75518897f1 Fixed Paginated Search 2025-10-31 16:29:20 +01:00
3bd4ac1f56 Added Notification Basics 2025-10-31 16:28:17 +01:00
2eb19b36a6 Added Helpdesk
Added M2M Auth
2025-10-31 16:27:56 +01:00
bbd5bbab9b Added Helpdesk 2025-10-27 17:40:43 +01:00
8ff63fadec Added Paginated Endpoint
Reformatted Code
2025-10-27 17:40:25 +01:00
8af09e1841 Added Paginated Endpoint
Reformatted Code
2025-10-27 17:39:32 +01:00
5d3cdeb960 Added Paginated Endpoint
Reformatted Code
2025-10-27 17:39:25 +01:00
d4fe665462 Added Standard E-Mail in Select 2025-10-27 17:38:11 +01:00
560b15ec93 Removed output 2025-10-27 17:37:57 +01:00
efaebb2f4e Added Save in Sent for emailAsUser.ts 2025-10-27 17:37:51 +01:00
9658ad621a Introduced Paginated Data, Listing to StandardEntitys 2025-10-14 15:13:30 +02:00
f918e735a5 fixed ts errors 2025-10-13 21:42:39 +02:00
4907dd478a Merge branch 'beta' into 'main'
2025.19.5

See merge request fedeo/software!25
2025-10-13 19:40:19 +00:00
31c7bd34b7 Merge branch 'devCorrected' into 'beta'
Fixed Show Workingtimes

See merge request fedeo/software!24
2025-10-13 19:35:34 +00:00
e0ed8f41bb Working times and tenant profiles 2025-10-13 21:33:28 +02:00
ef0af906ff Fixed standardE-Mail for Invoices 2025-10-13 21:32:59 +02:00
2d332f1ded Fixed Show Workingtimes 2025-10-13 21:32:22 +02:00
6c3189c8f0 Merge branch 'beta' into 'main'
2025.19.4

See merge request fedeo/software!23
2025-10-10 06:25:08 +00:00
4abb3917e6 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!22
2025-10-10 06:21:25 +00:00
59c32ef8d8 Fixed Load of existing Doc without Created_by 2025-10-09 18:29:24 +02:00
4514627ec0 Fixed Wrong Bic Key 2025-10-09 18:29:07 +02:00
ceae4972b8 Merge branch 'beta' into 'main'
2025.19.3

See merge request fedeo/software!21
2025-10-09 16:04:18 +00:00
4b754b5ef5 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!20
2025-10-09 16:00:38 +00:00
f7f239fcb9 Fixed Service Editing 2025-10-09 17:22:43 +02:00
78846fd85a Added Contract Column 2025-10-09 17:04:49 +02:00
33411c4e7d Added Errors for Plant and Contract 2025-10-09 17:02:30 +02:00
0a9731be37 Fixed Ansprechpartner Loading 2025-10-09 17:02:19 +02:00
7bf29ffe32 Fix Set Booked State 2025-10-07 15:05:39 +02:00
ce8e35b628 Merge branch 'beta' into 'main'
2025.19.3

See merge request fedeo/software!19
2025-10-06 14:39:21 +00:00
c85b61000a Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!18
2025-10-06 14:35:43 +00:00
39820d7122 Fix Composing 2025-10-06 15:51:40 +02:00
4054d1acf8 Fix Change Phase 2025-10-06 15:49:23 +02:00
02330e2173 Fix TaxType 2025-10-06 15:47:53 +02:00
7ab53557ce Merge branch 'beta' into 'main'
2025.19.2

See merge request fedeo/software!17
2025-10-05 15:34:57 +00:00
50f1ed8d41 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!16
2025-10-05 15:30:41 +00:00
f9b69be791 Cahnge token lifespan 2025-10-05 17:24:01 +02:00
c092696a9a Added E-Mail Account Saving 2025-10-05 17:23:39 +02:00
d1cf575845 Fixed Contract Modal Buttons 2025-10-05 17:23:09 +02:00
ce3f6323ea Tidying 2025-10-05 16:56:51 +02:00
008d96d0b8 Added Contract to Createddocuments 2025-10-05 16:56:41 +02:00
473980d6b4 Added Zahlungsart 2025-10-05 16:56:25 +02:00
625bb4be4a Added Banking Link to show Document 2025-10-05 16:15:51 +02:00
f74b717bc0 Added E-Mail Account Adding/Editing 2025-10-05 16:02:22 +02:00
ffb91586a0 Merge branch 'beta' into 'main'
2025.19.1

See merge request fedeo/software!15
2025-10-05 13:17:24 +00:00
103499a163 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!14
2025-10-05 13:00:58 +00:00
1fd568c562 Tidying 2025-10-05 15:00:21 +02:00
b61a3de40a Fixed Vorschau Reloading 2025-10-02 19:29:06 +02:00
c729c595ee Fixed Edit in Modal 2025-10-02 19:25:59 +02:00
f05c222c42 Fixed Product Creation Error 2025-10-02 19:23:42 +02:00
3b9c77f321 Merge branch 'devCorrected' into 'beta'
Revert "Deleted Loggin Output"

See merge request fedeo/software!13
2025-10-01 17:25:30 +00:00
ccf25a69f0 Deleted Loggin Output 2025-10-01 19:20:31 +02:00
5744e19344 Revert "Deleted Loggin Output"
This reverts commit 29a6d885b4.
2025-10-01 19:19:53 +02:00
29a6d885b4 Deleted Loggin Output 2025-10-01 19:18:25 +02:00
80d1d205a1 Merge branch 'devCorrected' into 'beta'
Added ENV Var for PDF Viewer License

See merge request fedeo/software!12
2025-10-01 17:08:24 +00:00
f81d9ebb40 Added ENV Var for PDF Viewer License 2025-10-01 19:04:25 +02:00
4588c2b9e9 Fixed Mailer 2025-09-29 20:49:29 +02:00
22ce0d6e7a Fixed Mailer 2025-09-29 20:47:25 +02:00
26cb53b231 Secrets 2025-09-29 20:45:22 +02:00
183313b550 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!11
2025-09-29 17:03:50 +00:00
f917d8e370 Added Types
Corrected Return
2025-09-29 18:50:35 +02:00
fc6e76d756 Added Types 2025-09-29 18:47:21 +02:00
8750ccbb7d Removed Critical Log Output 2025-09-29 18:40:22 +02:00
87411d9b87 Added Number Ranges to DataTypes with Holder in Creation 2025-09-29 18:40:13 +02:00
1dfcc694ef Added Types 2025-09-28 17:57:28 +02:00
67a86ed9ab Added ENV Var for PDF Viewer License 2025-09-28 17:49:22 +02:00
5f31d0a89c Added PDF Viewer 2025-09-28 17:47:26 +02:00
6d6f8b419a Added Types for Tickets 2025-09-28 17:47:17 +02:00
2cfdafa507 Added Env Vars 2025-09-28 17:47:03 +02:00
6d0f83fab1 Disabled TIckets 2025-09-28 17:46:55 +02:00
bae41efdf5 Changed to PDF Viewer 2025-09-28 17:46:41 +02:00
467410af6a Added API Base VAR for Runtime Config 2025-09-28 17:46:23 +02:00
5b09a11a6e Added API Base VAR for Runtime Config 2025-09-28 17:45:46 +02:00
72f8064d06 Fixed E-Mail Sending for New Api 2025-09-28 17:45:28 +02:00
a222da1970 Fixed Spaces 2025-09-28 17:45:10 +02:00
3cbd6b265e Removed Env Vars from Compose 2025-09-28 17:44:43 +02:00
9aefa5d08f Added E-Mail Sending Features 2025-09-28 17:44:31 +02:00
f51ced1c31 Added Types for Tickets 2025-09-28 17:44:17 +02:00
f683f149e6 Added S3 Init Function 2025-09-28 17:44:00 +02:00
7482e974f2 Introduced Crypt Functions 2025-09-28 17:43:44 +02:00
83fc24be0c Introduced Secrets Manager 2025-09-28 17:43:21 +02:00
4e61b20ba8 Removed 2025-09-28 14:32:21 +02:00
1c3c6adcc2 Removed Supabase 2025-09-28 14:32:11 +02:00
2a2078a85f Removed Supabase 2025-09-28 14:28:19 +02:00
3e17709998 Removed Supabase 2025-09-28 14:27:29 +02:00
e2b24964bc Removed Supabase 2025-09-28 14:26:51 +02:00
cfcbdfb749 Removed Supabase 2025-09-28 14:24:58 +02:00
fbf8e883d9 Removed Supabase 2025-09-28 14:24:52 +02:00
969fa60518 Removed Supabase 2025-09-28 14:24:46 +02:00
63ee3c7b9f Removed Supabase 2025-09-28 14:24:40 +02:00
6bb1222e0b Removed Supabase 2025-09-28 14:24:32 +02:00
baa59f16ce Removed Supabase 2025-09-28 14:24:25 +02:00
906e893bf0 Removed Rights 2025-09-28 14:24:17 +02:00
c68fe87622 Removed Old Update and Create 2025-09-28 14:21:19 +02:00
7851dd80ca Removed Old Update and Create 2025-09-28 14:21:12 +02:00
c95cc818b5 Removed IncomingInvoices Create 2025-09-28 14:20:02 +02:00
25483dd8f2 Removed TrackingTrips 2025-09-28 14:19:06 +02:00
c81ab45919 Merge branch 'devCorrected' into 'beta'
fixed archived filtering

See merge request fedeo/software!9
2025-09-26 16:22:38 +00:00
4d9b1f1dff Removed Archived 2025-09-26 18:13:17 +02:00
3aed09d023 Removed package-lock.json
Migrated Capacitor
2025-09-26 17:47:28 +02:00
68763996ad Removed Nuxt Content Module 2025-09-26 17:46:59 +02:00
347bc0cf7b Removed PDF Viewer Size 2025-09-26 17:46:26 +02:00
29b12cdc46 Changed Toolbar in PDFViewer 2025-09-26 17:46:02 +02:00
0e03a5914b Renamed useErrorLogging.js to prevent error from nuxt 2025-09-26 17:45:25 +02:00
936c6cdf00 Introduced PDFViewer 2025-09-25 18:32:20 +02:00
efba076c41 Removed some Entries in EntityShow because not working 2025-09-25 17:21:13 +02:00
7f0f6567b0 DocumentDisplay On Mobile 2025-09-25 17:20:54 +02:00
e5696191af Tidying 2025-09-25 17:20:33 +02:00
62c403307f Fixed some Redirects for Mobile
Fixed other Login stuff on mobile
2025-09-25 17:19:46 +02:00
7f2a6ba438 Added Maintenance Modes TO APP 2025-09-25 16:45:37 +02:00
9afd5c3bf5 Fixed Redirect Loop when already on /mobile 2025-09-25 16:45:25 +02:00
dd2bf7a8ff Added ArchiveButton.vue 2025-09-24 19:43:04 +02:00
4a05bd5bc3 removed dev output 2025-09-24 19:33:07 +02:00
850ef006c5 fixed archived filtering
added tabs to incominginvoices
added Badges to tabs
2025-09-24 19:33:00 +02:00
ce39e96c0a added Filters and templatecolumns in datatypes 2025-09-24 19:32:25 +02:00
2366790cc0 Added Link Button to Createddocuments when linked document is Present 2025-09-24 17:52:55 +02:00
4fa752f7c9 Changed App Version for IOS 2025-09-24 17:51:12 +02:00
76e1a333dc Added Capacitor isNative Function 2025-09-24 17:51:02 +02:00
0da2beaa64 Added Capacitor preferences 2025-09-24 17:50:46 +02:00
40c12ae487 Added Capacitor preferences 2025-09-24 17:50:41 +02:00
2656341956 Added Capacitor preferences 2025-09-24 17:50:34 +02:00
9894f003e3 Added new Auth Store 2025-09-24 17:50:20 +02:00
b57b11ca9a Added Redirect to mobile Index 2025-09-24 17:50:02 +02:00
46d0cbfd41 Removed not Functioning Cards 2025-09-24 17:49:49 +02:00
a207237bc2 Renamed EntityTableMobile.vue 2025-09-24 17:49:27 +02:00
476b4b5d4f Fied Display Welcome 2025-09-24 17:49:08 +02:00
911f5f049a Implemented Native Token Storage other than Cookies 2025-09-24 17:48:56 +02:00
5588d5a76c Fixed Layout Issues 2025-09-24 17:48:29 +02:00
0ae247ac98 Added Capacitor CORS 2025-09-24 16:55:18 +02:00
8480ce1512 Fixed Error when no IDs are present 2025-09-20 19:07:03 +02:00
07b914675d Fixed Error when no IDs are present 2025-09-19 17:08:59 +02:00
64d4569655 Removed Archived Filtering 2025-09-19 17:08:43 +02:00
8ab20cee51 Merge branch 'devCorrected' into 'beta'
Added Archived Showing,

See merge request fedeo/software!8
2025-09-19 14:01:35 +00:00
3f4636d698 Removed Driver from Vehicles until Users is built 2025-09-19 15:35:17 +02:00
cc9f7e58ec Removed Type Filtering, reduntant to tabs 2025-09-19 15:30:53 +02:00
168ebead92 Added Archived Showing,
Fixed Archived Filtering
2025-09-19 15:30:33 +02:00
f79c569383 Added Archived Showing,
Fixed Archived Filtering
2025-09-19 15:26:05 +02:00
b67e4cc6d2 Fixed Files Loading 2025-09-18 17:13:45 +02:00
cb19fa63f8 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!7
2025-09-17 19:29:32 +00:00
fd3ac28ae2 Fixed IncomingInvoices 2025-09-17 21:25:20 +02:00
e504ca60ce Fixed SerialInvoices 2025-09-17 21:25:11 +02:00
d3f70942b2 Changed Resources with Info 2025-09-16 18:34:48 +02:00
51ca916056 Merge branch 'devCorrected' into 'beta'
Fixed Createddocuments in Projects

See merge request fedeo/software!6
2025-09-16 16:34:08 +00:00
4ae55a4956 Fixed Createddocuments in Projects
Fixed FinalInvoices
2025-09-16 18:29:20 +02:00
a23376c727 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!5
2025-09-16 16:26:17 +00:00
55ac79c717 Corrected Archiving UX 2025-09-16 17:34:07 +02:00
95a122c4bf Fixed Loading Error at Login/Tenant Switch 2025-09-16 17:33:57 +02:00
f30ccd6c45 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!4
2025-09-15 15:43:41 +00:00
cd1d9f4cf2 Added Message 2025-09-13 18:13:19 +02:00
caa92843b3 Changed Backend URL 2025-09-13 18:11:09 +02:00
717eaf0851 Added Cors Hosts 2025-09-13 18:10:43 +02:00
975acb9833 Merge branch 'devCorrected' into 'beta'
Dev corrected

See merge request fedeo/software!3
2025-09-13 15:39:19 +00:00
85479435b0 Added created_by Error 2025-09-13 17:34:42 +02:00
d134f5541d Fixed Loading in Edit 2025-09-13 17:32:28 +02:00
18b63272b7 Changes 2025-09-13 17:32:21 +02:00
e60c0df77b Changed Error Page 2025-09-13 17:14:50 +02:00
eea7937225 Added Pinning to Standard Entity 2025-09-13 17:08:30 +02:00
9fad0eafd0 Added Archiving to Created Documents 2025-09-13 16:32:37 +02:00
91a62f88d2 Added Cors Hosts 2025-09-13 16:23:53 +02:00
8f0e5ad37a Merge branch 'devCorrected' into 'beta'
Added select-special

See merge request fedeo/software!2
2025-09-13 14:05:05 +00:00
cf42caa519 Changed Backend to Hosted 2025-09-13 16:00:31 +02:00
8f7ce314fb Changed host 2025-09-12 19:51:05 +02:00
d45d16a810 Changed host 2025-09-12 19:50:34 +02:00
0fe16ad79e Changed types 2025-09-12 19:40:53 +02:00
af1bf82c75 Changed Dockerfile 2025-09-12 19:30:01 +02:00
9b6af75e98 Changed Dockerfile 2025-09-12 19:28:35 +02:00
f35d375c5f Changed Dockerfile 2025-09-12 19:27:21 +02:00
522af71f9b Changed tsconfig 2025-09-12 19:23:18 +02:00
1dfc1fd2c1 Changed tsconfig 2025-09-12 19:22:05 +02:00
a9d0a060b8 Changed tsconfig 2025-09-12 19:21:24 +02:00
d3104bb5a2 Changed tsconfig 2025-09-12 19:18:51 +02:00
800b7d883e Changed Dockerfile 2025-09-12 19:16:37 +02:00
6d190d2501 Changed Dockerfile 2025-09-12 19:13:50 +02:00
0f03deeadd Changed Dockerfile 2025-09-12 18:59:08 +02:00
fc46e807e7 Added Running Config 2025-09-12 18:38:13 +02:00
c98394b5bf Changes 2025-09-12 18:29:13 +02:00
95e8da2e39 Fix Porfile Index 2025-09-12 18:28:53 +02:00
a19aa47e34 Fixed Accounts for new Backend 2025-09-12 18:22:15 +02:00
00d9361aad Fixed Createddocuments Sort 2025-09-12 18:13:24 +02:00
577e5d947a Added MaxLength 2025-09-12 18:07:05 +02:00
1985f7b725 Minor Change in E-Mail New 2025-09-12 17:45:02 +02:00
30da08689d Implemented new Backend in E-Mail Sending
Implemented Blob Return Method for File Download
2025-09-12 17:42:24 +02:00
9a210bceb9 Added navigate to archive in use entities
added archiving in incoming invoices
2025-09-07 19:45:45 +02:00
8302b00a9c Corrected displayIncomeAndExpenditure.vue displayOpenBalances.vue 2025-09-07 19:39:14 +02:00
0d918b8719 added createdletters 2025-09-07 19:36:37 +02:00
278afb5ee8 Fix partly email 2025-09-07 19:34:24 +02:00
c7e18d689e Fix Createddocs 2025-09-07 19:32:59 +02:00
6d233f5bfb Fixed incoming EDIT, useFiles, useFunctions, usePermission 2025-09-07 19:29:41 +02:00
949b094490 Fixed auth, NAV, projecttypes,numberranges,tenant,textemplates 2025-09-07 19:26:46 +02:00
34c5764472 Added select-special
Fixed Banking Page
2025-09-07 19:20:50 +02:00
9f59b94336 Removed Unused Files 2025-09-07 19:10:08 +02:00
f5f2949545 Added Export Page 2025-09-07 19:09:23 +02:00
01e3d878d3 Changed Main NAV 2025-09-07 19:09:15 +02:00
45741a6295 New Backend changes 2025-09-07 19:04:39 +02:00
42edd626fd New Backend changes 2025-09-07 18:59:08 +02:00
af86fdd8ed New Backend changes 2025-09-07 18:59:04 +02:00
dc385b8422 Changes 2025-09-02 19:11:05 +02:00
8d5e158d59 New Backend changes 2025-09-02 19:10:59 +02:00
7c4272ffe9 Changes 2025-09-02 18:47:44 +02:00
27af6a0953 New Backend changes 2025-09-02 18:47:12 +02:00
97a095b422 Changes 2025-08-31 18:29:29 +02:00
6d76acc0bc New Backend changes 2025-08-31 18:28:59 +02:00
aeaba64865 Initial commit 2025-08-29 14:44:56 +00:00
c492442d3d Merge branch 'refs/heads/beta' 2025-07-31 21:02:08 +02:00
b0497142ed Tidying 2025-07-31 21:01:05 +02:00
95b1c16cf1 Added Title to FinalInvoice Load Mode 2025-07-31 20:46:15 +02:00
7265164b0a Tidying 2025-07-31 20:38:38 +02:00
841bb67d60 Added Title Transfer Sums 2025-07-31 20:38:30 +02:00
c70cd797ac Rebuild Inovice LoadModes 2025-07-31 20:37:51 +02:00
80d68e0aa9 Tidying 2025-07-31 20:34:29 +02:00
23573caceb Changed Global Messages to Modal 2025-07-31 20:28:35 +02:00
661e826767 Added Description 2025-07-31 20:20:35 +02:00
8989975be1 Added Steuertyp Error 2025-07-31 20:20:17 +02:00
a4d68cafd8 Combined Rechnungen, Abschlag and Storno 2025-07-31 17:52:35 +02:00
472ee0fd53 Added TempStore to createddocuments and incominginvoices 2025-07-31 17:52:17 +02:00
86a12cc223 Added net Sums to Tax 2025-07-24 15:20:42 +02:00
01469d97f0 Added Tabs to Createddocuments Index 2025-07-23 20:38:27 +02:00
c58b6ca2aa Fix displayIncomeAndExpenditure.vue 2025-07-23 20:33:46 +02:00
58ef4ec620 Removed Unused Function 2025-07-22 17:46:27 +02:00
e3c3a5c444 Changed Supabase Selects 2025-07-22 17:46:00 +02:00
a7336999ef Fixed Scroll 2025-07-22 17:45:37 +02:00
0e3586dccf Some Fixes in Times 2025-07-22 17:45:16 +02:00
2490c69beb Added Vars in texttemplates.vue 2025-07-22 17:44:50 +02:00
986f27a48c Added Multiple Tax Percentages
Fixed Pagebreak colspan
2025-07-22 17:44:09 +02:00
6bc8e4e7f0 Fixed Scroll 2025-07-22 17:13:34 +02:00
dcac52ff9d Fixed Gebucht in IncomingInvoice Edit 2025-07-15 16:28:36 +02:00
6cfaf3fdbe Fixed scroll in EntityShowSub.vue 2025-07-01 10:41:47 +02:00
10c686bfa1 Corrected Set Booked 2025-06-30 14:23:22 +02:00
f77ffeaf4c Added Remove Vendor 2025-06-30 14:11:20 +02:00
ff6ee91075 Added Errors to IncomingInvoices
Added Vorbereitet to IncomingInvoices
2025-06-30 13:45:06 +02:00
93d0f97a56 Added search to serialinvoices 2025-06-27 18:23:54 +02:00
e5b4409df7 Fixed Storno 2025-06-27 18:02:22 +02:00
f4fae86d31 Added Display for cancelled Invoices 2025-06-27 17:46:17 +02:00
fe8aa2e758 Added getIsPaid 2025-06-26 11:37:51 +02:00
0209c49503 Changes 2025-06-26 11:37:39 +02:00
2b1e2a12eb Changes 2025-06-26 11:37:28 +02:00
e98e1dc634 Changed some in EntityShowSubCreatedDocuments.vue 2025-06-26 11:36:54 +02:00
583ca15dcc Added Sorting and Display Rendering 2025-06-26 11:35:17 +02:00
1264b987fe Added openSum 2025-06-26 11:34:46 +02:00
ffec9b7dc4 Fixed Overdue Invoices 2025-06-26 11:34:04 +02:00
a742fc8c54 EDIT Graph 2025-06-26 11:33:29 +02:00
cf8845848a Changed Redirect after Create 2025-06-26 11:31:30 +02:00
6b1e697209 Added Dev Only Logging 2025-06-26 11:31:16 +02:00
a6b9247305 Added Dev Only Logging 2025-06-26 11:31:12 +02:00
bfc11bcace Added AI Suggestion to IncomingInvoice Create 2025-06-07 16:44:27 +02:00
132016f562 Added AI Suggestion to IncomingInvoice Create 2025-06-07 16:34:44 +02:00
96cd94d77f Cahnges in Projektzeiten and Naming 2025-06-07 16:33:57 +02:00
bab0187467 Fix for Leistungszeitraum in SerialInvoices 2025-06-07 16:33:16 +02:00
8d4ff3c88e Added Features to Mobile Styling 2025-06-03 16:35:30 +02:00
dd89a70789 Corrected Markup Calc in Products 2025-06-03 16:35:10 +02:00
50e583389e Merge branch 'refs/heads/beta' 2025-06-01 18:37:27 +02:00
ef8e0d0e83 Added Tenant Changing in App 2025-06-01 18:30:57 +02:00
08f104d4c9 Added Times Entry for in project Display 2025-06-01 18:23:34 +02:00
4346fbffe5 moved times/index 2025-06-01 18:23:14 +02:00
03231ab3f3 added displayRunningTime.vue 2025-06-01 18:23:01 +02:00
80f05c7029 moved displayRunningTime.vue to displayRunningWorkingTime.vue 2025-06-01 18:22:41 +02:00
5199afb9b5 Changes to Word Breaking 2025-06-01 18:22:20 +02:00
3fa50c158c Merge branch 'refs/heads/beta' 2025-05-31 20:45:35 +02:00
cdbf1785a3 Added Pagebreak to Workintime Evaluation 2025-05-31 20:45:04 +02:00
3eadedcb19 removed vite pwa 2025-05-31 20:10:49 +02:00
4e469a3ffc fix for optional and alternative 2025-05-31 20:10:38 +02:00
f93eb9ec71 Added Markup Percentage for Products 2025-05-31 20:10:14 +02:00
eb37257ae8 Some Corrections For Mobile 2025-05-31 20:09:36 +02:00
bb99d5ae1c Added Optional and Alternative in Quotes
Redesigned the Row Edit Modal
Added Errors for Optional and Alternative Rows
2025-05-25 16:39:03 +02:00
e982684d95 Removed Required for Lastname in Customers 2025-05-25 16:39:03 +02:00
e2e368e9f8 Removed Log Output 2025-05-25 16:39:03 +02:00
4a3c4f4bd7 Added Support for Conditional Rendering of Inputs
Added Some InputColumns in anticipation of required InputColumns
2025-05-25 16:39:02 +02:00
fd3b96a11c Added Support for Conditional Rendering of Inputs 2025-05-25 16:39:02 +02:00
9d3aba9179 Added Name Edition to Company Customers 2025-05-25 16:39:02 +02:00
1b30825b76 Fixed BCC when no standard E-Mail is present 2025-05-25 16:39:01 +02:00
6f6754db39 Rechnungs E-Mail Adresse zu Kunden hinzugefügt 2025-05-25 16:39:01 +02:00
f1eb857eda Removed Text Justify in GlobalMessages.vue 2025-05-25 16:39:01 +02:00
cad2ed9dba Added Editing for Automatic Working Hour Corrections 2025-05-25 16:27:56 +02:00
c94e4c3194 Added Optional and Alternative in Quotes
Redesigned the Row Edit Modal
Added Errors for Optional and Alternative Rows
2025-05-25 15:54:08 +02:00
6599fdc6c2 Removed Required for Lastname in Customers 2025-05-25 15:53:14 +02:00
f5431ddade Removed Log Output 2025-05-20 17:15:01 +02:00
835486d04f Added Support for Conditional Rendering of Inputs
Added Some InputColumns in anticipation of required InputColumns
2025-05-20 17:13:06 +02:00
db53043b19 Added Support for Conditional Rendering of Inputs 2025-05-20 17:12:35 +02:00
131a7a95b9 Added Name Edition to Company Customers 2025-05-20 16:52:17 +02:00
6a68c2fbcd Fixed BCC when no standard E-Mail is present 2025-05-20 16:24:16 +02:00
5606858dc7 Rechnungs E-Mail Adresse zu Kunden hinzugefügt 2025-05-20 16:24:02 +02:00
b17af2620b Removed Text Justify in GlobalMessages.vue 2025-05-20 16:18:47 +02:00
55038d2bcb Added Salutation and Title to Customer and Contact
Added Vars to GenerateContext for Salutation and title
2025-05-18 19:09:32 +02:00
a0ffdce1bb Added Saldo and Count 2025-05-13 17:06:55 +02:00
a9ea5982cf Fixed Profile Selection 2025-05-13 15:59:02 +02:00
557d0eff2f Fixed Texttemplates and Title Import from Copy 2025-05-13 15:43:59 +02:00
241a912f08 Added Statements to OwnAccounts 2025-05-08 11:08:00 +02:00
caba8348bf Added rows length condition to auswertung 2025-05-07 19:15:59 +02:00
3332b7f258 Cahnged Color 2025-05-07 19:15:41 +02:00
f1ef5fce58 Fixed Typo 2025-05-07 19:15:34 +02:00
b647518d2f Fixed Driver 2025-05-03 12:52:52 +02:00
834f96f258 Added Display for Dokubox 2025-05-02 17:03:35 +02:00
57b7d0b35b Fixed Booking Sum 2025-04-30 15:13:06 +02:00
1679bfdc7d Changed Colors
Added IncomingInvoicesUnfinishedCount
2025-04-24 15:42:58 +02:00
d9dc7c67be Changed Linebreak in Dashboard Accounting 2025-04-24 15:36:24 +02:00
3986c9cd0a Added Search to Files 2025-04-24 15:34:34 +02:00
e71118ad09 Corrected Assigning 2025-04-24 15:19:22 +02:00
795a8662f9 Fixed Auswertung Calc 2025-04-24 15:03:05 +02:00
81165c6954 Added Filter Saving in Banking 2025-04-24 14:56:53 +02:00
c419fe610d Added Filters to Banking 2025-04-24 14:53:55 +02:00
87dc8ead08 Added Dots to useCurrency.js 2025-04-23 09:16:50 +02:00
c231994ad1 Added Count to Eingangsbelege Index 2025-04-22 15:32:30 +02:00
fe8902ba7f Added Separation to Offen/Überfällig 2025-04-22 15:32:19 +02:00
f4f28c095d Merge branch 'dev' into beta
# Conflicts:
#	package-lock.json
2025-04-22 14:47:06 +02:00
50a22877e4 Added Default Payment Method to Vendors
Added Auto Select to Create incoming
2025-04-22 14:46:12 +02:00
1b2bc1424d Added Account Sorting 2025-04-22 14:38:20 +02:00
e6c9942d7d Added File Sorting 2025-04-22 14:37:41 +02:00
3998c997d4 Fixed Create Vendor 2025-04-22 14:18:22 +02:00
207ed7ce36 Fixed Search for Customers in Banking 2025-04-22 14:12:30 +02:00
415dbed67a Merge branch 'dev' into beta 2025-04-22 09:38:06 +02:00
e3196460b9 Fixed Open Calc 2025-04-22 09:37:59 +02:00
34b566343f Fixed Calc on select 2025-04-22 09:37:47 +02:00
7b4d6d7858 Merge branch 'dev' into beta 2025-04-21 13:40:20 +02:00
b310d96482 app changes 2025-04-21 13:40:07 +02:00
9877206825 tidying 2025-04-21 12:20:48 +02:00
7fd088b758 Removed Wrap 2025-04-21 12:20:30 +02:00
8220db14f3 Fixed Document Number in banking 2025-04-19 21:25:21 +02:00
dc79787f70 fixed tab change with arrows 2025-04-19 21:12:13 +02:00
0272c9434c fixed update 2025-04-19 21:11:54 +02:00
658e3f66b3 Merge branch 'dev' into beta 2025-04-19 17:48:52 +02:00
0d8f403058 added report saving
added var lohnkosten to generatecontext
2025-04-19 17:48:42 +02:00
4623bb3bb7 Merge branch 'dev' into beta 2025-04-19 17:35:12 +02:00
ec741acf7c Added THs 2025-04-19 17:34:58 +02:00
8edd996b89 Added Document Report 2025-04-19 17:34:45 +02:00
d762bb3228 Added Personal Composition 2025-04-19 17:34:29 +02:00
842afcfdb2 Added Hourrates 2025-04-19 17:34:02 +02:00
e17f8aa734 Merge branch 'refs/heads/dev' into beta 2025-04-17 14:10:14 +02:00
577b2dd035 Removed Paid and DueDate in Drafts 2025-04-17 14:09:58 +02:00
8f6ca1593e added archived filtering 2025-04-17 14:07:58 +02:00
7e95547eb1 Removed debug info 2025-04-17 14:07:49 +02:00
8d39c16e26 Added displayBankaccounts.vue 2025-04-17 14:00:00 +02:00
fa25923e62 Removed Bank Bookings from displayOpenBalances.vue
Added displayBankaccounts.vue
2025-04-17 13:54:32 +02:00
b9cd79cabe Fixed Mode in StandardEntityModal.vue 2025-04-17 13:47:05 +02:00
6049fcbb1b Added Tenant sorting 2025-04-16 12:44:14 +02:00
93b36be42c Displaying correction
Fixed Week selector
2025-04-16 12:44:06 +02:00
e21e46b2c8 Changed Open Sum Calc in displayOpenBalances.vue 2025-04-14 19:06:19 +02:00
78b16d2c1c Merge branch 'dev' into beta 2025-04-14 18:56:54 +02:00
9afe62eae5 Changed DC.yml 2025-04-14 18:56:44 +02:00
bd2fe9bb03 Merge branch 'dev' into beta 2025-04-14 15:11:25 +02:00
dd10760da1 Fix Calc in Banking Index
Show Document Ref instead of Partner Ref
2025-04-14 15:11:18 +02:00
3bf54a4e32 Merge branch 'dev' into beta 2025-04-14 13:21:19 +02:00
7750415e9a Fix Table Select 2025-04-14 13:21:10 +02:00
ba1aa84ac4 Merge branch 'dev' into beta 2025-04-14 13:13:38 +02:00
9d89b547b2 Fix Table Select 2025-04-14 13:13:27 +02:00
808df9a6ad Merge branch 'dev' into beta 2025-04-14 10:15:30 +02:00
abc10a77f8 Changed to HTML 2025-04-14 10:15:23 +02:00
bc5ba9c352 Merge branch 'dev' into beta 2025-04-12 12:31:53 +02:00
554f871a1a Added IncomingInvoices to Accounts 2025-04-12 12:31:47 +02:00
af90c6fcf3 Fixed DocumentUpload and Loading in Files 2025-04-12 12:06:52 +02:00
977e9e0344 Fixed DocumentUpload and Loading in Files 2025-04-12 12:01:21 +02:00
b924c92908 Added TabIndex to Route in Standard Entity 2025-04-12 11:30:51 +02:00
b7ff4a915b Added Rights for DocumentBoxes 2025-04-12 11:26:00 +02:00
56334128ae Corrected Type 2025-04-12 11:25:50 +02:00
fe14591e02 Changed Document Upload to the Upload Modal 2025-04-12 11:25:38 +02:00
ab7f8b0846 Made Card Fullscreen 2025-04-12 11:25:18 +02:00
bb4aea512d Changed PDF Detection 2025-04-12 11:25:08 +02:00
f49d6f45b6 Added DocumentBoxes 2025-04-12 11:24:48 +02:00
74be47b84c Merge branch 'dev' into beta 2025-04-11 18:31:32 +02:00
1a29b47583 Added Pages for Accounts with Allocation Listings 2025-04-11 18:31:16 +02:00
d3b4f217e2 Added Pages for Accounts with Allocation Listings 2025-04-11 18:31:10 +02:00
cfcfceb9e8 Adde Back Button 2025-04-11 18:30:49 +02:00
5b913799d0 Umami Umstellung 2025-04-09 20:24:45 +02:00
f0c96f5e10 Corrected TaxType Saving and Display of DeliveryDate when "Kein Lieferdatum anzeigen" 2025-04-09 20:24:30 +02:00
e45ff93100 Counter in BankingStatement 2025-04-08 15:33:04 +02:00
05b47fa2e9 tidying 2025-04-05 19:55:34 +02:00
c53154d115 tidying 2025-04-05 19:46:16 +02:00
e79d034c2c Added Glitchtip 2025-04-05 19:36:44 +02:00
1136d59f20 Added Glitchtip 2025-04-05 19:36:39 +02:00
b1ed0b17ed added globalmessages removed condition on Search Button 2025-04-05 19:36:10 +02:00
8604a18ed5 moved filter 2025-04-05 19:35:36 +02:00
267b68283f added globalMessages 2025-04-05 19:35:16 +02:00
a47426af70 Added Statement Description to Allocations 2025-04-01 16:19:13 +02:00
035b5f2eac removed PhasesTemplates Remainings 2025-04-01 16:18:42 +02:00
70000c776e removed getDocumentSum Function 2025-04-01 16:18:21 +02:00
8593720c15 corrected isphone loading 2025-04-01 16:17:45 +02:00
9f5409cc70 added redirectToMobileIndex.ts 2025-04-01 16:17:28 +02:00
621c61c094 added type change and rounding to useSum 2025-04-01 16:17:07 +02:00
b5287f4a7d Merge branch 'devWithMobile' into dev 2025-03-30 16:52:06 +02:00
5f483b4980 Corrected Icons in Footer 2025-03-30 16:51:48 +02:00
ff5593ebc5 Added Redirect if User is not on Mobile Index 2025-03-30 16:51:38 +02:00
684f65250f Capcitor/Xcode Config / REDO 2025-03-28 18:01:28 +01:00
7a986189df Added Mobile Rendering to EntityShow 2025-03-28 17:25:31 +01:00
a3bec6a9b1 Introduced EntityShowSubComponents 2025-03-28 17:05:08 +01:00
ea6181265d Added Right Side to Toolbar 2025-03-28 17:04:57 +01:00
65e1025289 Removed Path Subconfig in nuxt.config.ts 2025-03-28 17:04:46 +01:00
a144bba54b Introduced EntityTable 2025-03-28 17:04:27 +01:00
7f8efcf32f Added Scroll Class 2025-03-28 17:04:12 +01:00
95968681ce Changed Supabase Select Query for Projects 2025-03-28 17:04:00 +01:00
338bcd0df9 Conditional Rendering 2025-03-28 15:02:59 +01:00
eeec6d2f92 Simplified GetIsPhone Return 2025-03-28 15:02:50 +01:00
6ea58d7990 Changed Bottom Spacing 2025-03-28 15:02:15 +01:00
7d3cba7e79 Added Orientation 2025-03-28 15:01:56 +01:00
f4ab1b382d Renaming 2025-03-28 15:01:46 +01:00
d9a2384701 Added Assets for Splash and App Icon 2025-03-28 15:01:37 +01:00
235f3690cb Disabled Devtools and Hot Reload 2025-03-28 15:01:11 +01:00
548e85a00a Added Phone Redirect 2025-03-28 15:00:56 +01:00
4d2401ff59 Fixed Setup Query 2025-03-28 15:00:38 +01:00
eac0a6573a Removed User Zoom 2025-03-28 15:00:24 +01:00
c77198625c Fixed Setup Query 2025-03-28 15:00:03 +01:00
b3fd996f3f Some Changes 2025-03-27 20:36:08 +01:00
830c71ada7 Added ContractNumber Field 2025-03-27 16:10:50 +01:00
4fbde89251 Added Filters to Serial Invoice 2025-03-27 16:00:56 +01:00
9eae5740a8 Corrected Error in SerialInvoice Creation 2025-03-27 15:30:37 +01:00
c019b2608c Changed Date Type in contracts
AAdded Sign Date and SEPA Date
2025-03-27 15:25:17 +01:00
57a4512a0e Changes 2025-03-27 14:33:34 +01:00
7deffc885e Merge branch 'dev' into devWithMobile 2025-03-25 15:17:34 +01:00
b33ad857b1 Added Archiving 2025-03-24 19:07:26 +01:00
207d9ce5f6 Corrected Spacing on Right Side 2025-03-24 18:54:39 +01:00
ee1aa1bbed Changed Booking
Changed Columns in Incoming Invoices
2025-03-24 13:33:39 +01:00
856ebd1b60 Cahnges to make compatible 2025-03-24 11:55:32 +01:00
bb7d7ae3a9 Cahnges to make compatible 2025-03-24 11:54:56 +01:00
5418c0195e Added Plugins for Network, Device and Plattform 2025-03-23 16:35:37 +01:00
35c98ebb97 Corrected Display for Created Documents 2025-03-23 16:35:19 +01:00
6cb9653dea Changed Sidebar Footer to Full W 2025-03-23 16:10:58 +01:00
f0550f5233 Added OneSignal 2025-03-23 16:08:15 +01:00
f21cd63367 Made Index Scrollable 2025-03-23 15:21:17 +01:00
325c37e26e Made Hilfe&Info Sticky 2025-03-23 15:21:07 +01:00
4ff9fed3df Added OneSignal Cordova 2025-03-23 15:20:50 +01:00
ff69796eab Added Assets 2025-03-23 15:20:42 +01:00
cd7cecb61b Remove package-lock.json 2025-03-23 14:47:52 +01:00
e85a1def90 Added CAp Dir 2025-03-23 13:18:27 +01:00
ba72a896bb Added Capacitor 2025-03-23 13:17:03 +01:00
b5b1741f21 Added Ability to Book to Customers and Vendors 2025-03-23 13:09:56 +01:00
19a5d906da Removed temp Store in Datastore 2025-03-23 13:08:56 +01:00
34e6fb7b64 Added Customer to Events 2025-03-23 13:08:45 +01:00
bd15ac8b2d Added Kostenstellen und Buchungskonten 2025-03-21 14:53:27 +01:00
76e207cd20 Introduced OwnAccounts
Introduced CostCentres Rebuild
Added EntityModalButtons to IncomingInvoice Create
2025-03-21 14:24:05 +01:00
bd1916bdaa Corrected Column Rendering 2025-03-21 12:23:06 +01:00
3dcaeb1d4f Corrected Some Rendering
Corrected Booking Sum
2025-03-21 12:20:02 +01:00
f1fa6d2762 Corrected Title Colspan 2025-03-18 09:53:09 +01:00
bb4b9734aa Added PV Mode for Documents 2025-03-18 09:52:58 +01:00
78b0ee6f9b Added Compatibility Check for Old Documents
Added Width to Product and Service Select
2025-03-18 08:16:41 +01:00
6d234ffb5b Corrected Error 2025-03-17 14:09:05 +01:00
be4f586613 Merge branch 'refs/heads/dev' into beta 2025-03-16 19:14:15 +01:00
02b8768f8e Fixed CustomSurcharge and Introducted Input Price 2025-03-16 19:13:58 +01:00
38be27a89c Fix in Archived Filtering 2025-03-16 18:39:36 +01:00
cff5d9be29 Rebuild Document Copy Process 2025-03-16 18:36:12 +01:00
11594e6dc7 Fixed Create Change 2025-03-16 18:36:00 +01:00
44e8ce0105 Made SellingPrice Total required in Services 2025-03-16 18:01:21 +01:00
ea7ffaca5d Removed Steuer & Rabatt from Direct View 2025-03-16 18:00:57 +01:00
898663344b Added Create,Edit,Show to Products and Services 2025-03-16 18:00:37 +01:00
15a889dfcf Added Archivable Prop to Datatypes wich are archivable
Added Filtering to SupabaseSelect Composable for Archived
2025-03-16 17:36:16 +01:00
5442accb48 Merge branch 'refs/heads/dev' into beta 2025-03-14 18:32:47 +01:00
b7d64b1f9e Added Tenant Filtering 2025-03-14 18:32:36 +01:00
aa849f591b Added Standard File Type in Folders and Made it optional 2025-03-14 18:07:21 +01:00
c3fcb83da2 Added Remove Button to CostCentre in IncomingInvoices 2025-03-14 17:54:15 +01:00
0d75678ffd Merge branch 'refs/heads/dev' into beta 2025-03-14 17:50:12 +01:00
d907f1ca01 Added Modals for Adding, Editing, Showing 2025-03-14 17:49:54 +01:00
e42dd9cc6e Removed Title from Freitext
Correct Advance Invoice Loading
2025-03-12 10:54:03 +01:00
14e4e79c43 Corrected Usesum 2025-03-10 14:59:54 +01:00
d83f31c3c2 Introduced central Sum for Createddocuments 2025-03-09 18:09:20 +01:00
6f47b12501 Added Editing to IncomingInvoices 2025-03-09 17:51:54 +01:00
99cd9dd195 Added Filter in banking to show only booked incominginvoices 2025-03-09 17:51:30 +01:00
5fb62313d4 Added Customer, Vendor to Events 2025-03-09 17:39:25 +01:00
41aa40b237 Added Open Tasks Card
Added Some Titles
2025-03-05 19:12:31 +01:00
1f5d4434be Removed Logs 2025-03-05 19:12:14 +01:00
3d83100eda Added Categorie Input to Tasks 2025-03-05 19:12:03 +01:00
29860684cb Fixed displayIncomeAndExpenditure.vue 2025-03-05 18:54:13 +01:00
4c6cce416d Added Filter "nur offene anzeigen" 2025-03-04 17:20:18 +01:00
449386a906 Fix Quickaction Buttons 2025-03-04 17:14:12 +01:00
3be4b4eb50 Merge branch 'beta' into dev 2025-03-04 17:10:36 +01:00
f8af82d0a8 Zurück zu Übersicht hinzugefügt 2025-03-04 17:09:49 +01:00
855f527a87 Fixed TaxType, Added Taxtype to Quotes and Confirmation Orders 2025-03-04 17:07:22 +01:00
69c056a35f added conditional rendering to checkbox 2025-03-04 15:53:12 +01:00
11e43e6a9b Added Disabling for moving 2025-03-04 15:52:30 +01:00
8b49ae373e Removed SerialInvoices
Added Clearing after Edit
2025-03-04 15:44:33 +01:00
b084f13f0c Corrected Banking page
Added Scroll
2025-03-04 15:37:38 +01:00
c616fe1154 Added Document Number trycatch 2025-03-03 11:36:27 +01:00
89cb068db6 Added Missing Unit Error
Added Surcharge in Saving
Added Contact Auto Loading when just one is present
2025-03-03 11:35:50 +01:00
c96ff65bc7 Added CustomSurchargePercentage
Added RowEdit Modal
2025-03-03 11:31:44 +01:00
57b631ad72 Added Required to Taxpercentage in Products and Services 2025-03-03 10:59:59 +01:00
7980efec50 Added UST Input for Services 2025-03-03 10:56:25 +01:00
79c1d2d361 Fixed Link in Incoming Invoice Create 2025-02-27 11:53:31 +01:00
ba0646e768 Added Push Notification for Ticket Messages 2025-02-27 09:37:08 +01:00
58a9d72946 Added Columnrendering for Driver 2025-02-27 09:28:00 +01:00
f3ce52d247 Added Start End Filtering for Texttemplates in Invoices 2025-02-27 09:21:18 +01:00
08acee792b Added texttemplates Archiving 2025-02-27 09:21:03 +01:00
183bac752e Corrected MainNav Textvorlagen 2025-02-27 09:20:52 +01:00
dc587029e1 Changed Textemplate Edit from Slideover to Modal 2025-02-27 09:11:14 +01:00
bb7cd71a07 Added TaxType automatic correction
Added Conditional Rendering for DocumentTotal in Editor
2025-02-27 08:49:41 +01:00
bb68f29d4d Corrected Christmas Logo 2025-02-27 08:49:07 +01:00
1b1ef80983 Corrected Ad Blue Calc
Added Adblue Usage and Price to Agridata Modal
2025-02-26 09:56:03 +01:00
eb99adafab Merge branch 'dev' into beta 2025-02-25 23:04:50 +01:00
96341185c0 Added some columnrenderings
Added InventoryitemGroups
Removed some stuff from dataStore
2025-02-25 23:01:00 +01:00
07e7c43a2e Merge branch 'dev' into beta 2025-02-24 04:00:23 +01:00
f1e50f7c38 Changed Abschlagszahlungen to Auto Create Position 2025-02-24 03:59:51 +01:00
288163aded Merge branch 'dev' into beta 2025-02-21 17:51:58 +01:00
4e37915516 Restructured Ticket Chat 2025-02-21 17:51:44 +01:00
53b13bc6a5 Added Reasons to absencerequests 2025-02-21 17:51:35 +01:00
ff27862bdd Added standard phases to projecttype creation 2025-02-21 17:33:03 +01:00
3eda49d468 remodel of texttemplates Screen 2025-02-21 17:30:03 +01:00
62e891f594 Restructured Banking Allocation 2025-02-21 17:19:42 +01:00
2ed4d9d1d4 Fixed Dropdown in incominginvoices 2025-02-21 17:19:26 +01:00
1beeb4ea6d Added 19 USTG 2025-02-21 17:17:40 +01:00
48ee83a77e Fixed Scroll 2025-02-21 16:43:51 +01:00
f01b307865 Added Ticket Badge 2025-02-21 16:37:08 +01:00
f315c920e7 Corrected Adblue Processing 2025-02-21 16:37:00 +01:00
79c169ef2a Introduced useSum Composable 2025-02-19 19:06:02 +01:00
ac6aa470af Corrected Vendor Link 2025-02-19 19:04:15 +01:00
e8263a8bb5 Corrected Archived in displayProjectsInPhases.vue 2025-02-19 13:08:34 +01:00
7c64447c9d Fixed Dropdown Truncation 2025-02-18 22:12:15 +01:00
2a728e0ee7 Fixed IsPaid for Incoming 2025-02-18 22:10:55 +01:00
855e137376 Added Search Temp Save 2025-02-18 22:10:23 +01:00
074985a2ac Fixed Colors 2025-02-18 22:10:10 +01:00
eedc8fe67f Fixed Counter Bankstatements 2025-02-18 22:04:53 +01:00
c63bcb9246 Merge branch 'dev' into beta 2025-02-16 18:47:35 +01:00
efd929b153 Removed JS Print Manager Packet 2025-02-16 18:47:21 +01:00
a7ed13ae9a Merge branch 'dev' into beta 2025-02-16 18:36:21 +01:00
8ffc070622 Removed JS Print Manager Packet 2025-02-16 18:36:06 +01:00
9e67654272 Changed Color in EntityEdit 2025-02-16 18:35:51 +01:00
d81d2d89d4 Added Required to Absence Reason 2025-02-16 18:35:34 +01:00
c1591099c6 Changed Event Title with Project 2025-02-16 18:35:13 +01:00
a84f906d43 Changed Recipient Rendering to Array 2025-02-16 18:34:54 +01:00
f6c1dc1cab Added startDateTime.vue endDateTime.vue
Added components to Events Datatype
2025-02-14 17:21:20 +01:00
e448bac0d8 Tidying 2025-02-14 17:17:51 +01:00
1c22561acc Fixed Archived 2025-02-14 17:16:36 +01:00
e1ee5a89f0 Merge branch 'dev' into beta 2025-02-13 18:26:37 +01:00
c75e97252c Fixed Calendar Display 2025-02-13 17:55:28 +01:00
20ec16c3d1 Added Adblue Calculation 2025-02-13 17:44:29 +01:00
36a039f72e Added Absence Reason Schulung 2025-02-13 17:44:17 +01:00
21f5b17673 XXXX in Entwurf for Dates 2025-02-13 17:36:06 +01:00
d675eb96a6 Some Fixes in Tickets 2025-02-13 17:30:00 +01:00
4401692de0 Merge branch 'dev' into beta 2025-02-12 10:20:08 +01:00
85ffd61c16 Added Required Values 2025-02-12 10:19:50 +01:00
abbc8bf945 Merge branch 'dev' into beta 2025-02-11 19:23:58 +01:00
291762a49e Changes 2025-02-11 19:23:30 +01:00
05d2575544 Changed Title of Absences 2025-02-11 19:23:14 +01:00
83b2120ef5 Added Sick Days 2025-02-11 19:23:02 +01:00
b0d99f0a86 Added Status to Tickets
Fixed Telegram Notification in Tickets
Added Ticket Closing
2025-02-11 19:22:52 +01:00
80af069669 Added Status to Tickets
Fixed Telegram Notification in Tickets
Added Ticket Closing
2025-02-11 19:22:49 +01:00
1dc71d5791 Added Sick Days 2025-02-11 19:22:05 +01:00
abc5b8ff38 Fixed Shortcuts 2025-02-10 12:11:46 +01:00
6dc61da519 Changed Base URL 2025-02-10 09:15:45 +01:00
52f3eb15a7 Introduced Help Tickets 2025-02-09 23:22:40 +01:00
524b4b17c8 Correction in workingtime pdf 2025-02-09 23:22:15 +01:00
c109344b07 Changed HelpSlideover 2025-02-05 22:16:19 +01:00
15e480d26d Corrected Document Loading 2025-02-05 22:16:06 +01:00
807503c88f Reactivated Kein lieferdatum 2025-02-05 15:11:09 +01:00
d05d5c687c Changes in Übernehmen Buttons 2025-02-05 15:10:49 +01:00
8b6aa4b502 Introduced Temp for Columns and Filters
Implemented Filters in createddocuments
2025-02-05 15:10:08 +01:00
d586f8d9a6 Added Titlesums Correction 2025-02-04 14:48:08 +01:00
4f72c53648 Added TitleSims 2025-02-04 12:45:50 +01:00
4bcce61829 Changes in EntityEdit Query Loading 2025-02-04 12:45:32 +01:00
aebfe7dac6 Added Events to Projects
Added Events to EntityShow.vue
2025-02-04 12:45:11 +01:00
2e45ff3561 Tiny Fixes in Workingtimes Evaluate 2025-02-03 20:17:02 +01:00
d3d7799812 Tiny Fixes in Profile Editor 2025-02-03 20:16:49 +01:00
984831eaff Added Ability to jump to Abgeschlossen 2025-02-03 20:02:42 +01:00
ceb0f7c33e Tidying
Added Color Check
Added Due Date = Date
Changed UST and Price
Relabled Button to Betrag aufteilen
2025-02-03 20:00:45 +01:00
75b6e630fb Tidying in Removing
Added ID Check to SetPosnumber
2025-02-03 19:59:54 +01:00
70cca68f30 Added Edit for Filetype 2025-02-03 18:11:22 +01:00
2a63ff827b Added File Download
Added File Loading Screen
2025-02-03 18:06:20 +01:00
ce52c983a8 Changed Soll stunden
Added dieser monat bis heute
2025-02-03 11:41:27 +01:00
cc81d18344 Changed Back Button 2025-02-03 11:05:47 +01:00
c207329a3e Introduced TempStore to Store SearchStrings and Selections etc 2025-02-03 11:05:35 +01:00
f4b0964e25 Merge branch 'beta' 2025-02-02 19:35:27 +01:00
162f516647 Added Document Date to Title pos
Added Automatic timespan
2025-02-02 19:34:38 +01:00
e459c0a4e5 Added Taxtypes
Added 13b
Added Error Check for Timespan
2025-02-02 18:30:37 +01:00
d5378f1f83 Added Plant 2025-02-02 18:13:35 +01:00
1d5471f463 Table Tidying 2025-02-02 18:12:03 +01:00
673f1b8d58 Table Tidying 2025-02-02 18:11:59 +01:00
85c7a18b1a Added Plant to createddocuments
Added Timespan to createddocuments
Changed Info to Array
Removed some Datastore remains
2025-02-02 18:11:48 +01:00
6676d6314b Changed Title of + Dokuemnt 2025-02-02 13:18:10 +01:00
8048d73551 Changes in CreateDocument Index 2025-02-02 13:04:40 +01:00
88103c01eb Cahnges in File Upload 2025-02-02 13:04:27 +01:00
06aa639ae4 Cahnged Hochladen to + Datei 2025-02-02 11:53:26 +01:00
7385fc1a7e Added Archived Sorting to Banking 2025-02-02 11:53:12 +01:00
3711fa75cf Added Badge In Serial Invoices 2025-01-31 12:33:12 +01:00
66feca3323 Added Archived
Changed fucntions baseurl
2025-01-31 11:15:35 +01:00
148619eb05 Changed PDF Creation to Functionsserver 2025-01-30 14:32:23 +01:00
30a658b083 added Tenant ordering 2025-01-29 18:12:02 +01:00
4f45bd2b76 Changed None to keine phase 2025-01-29 18:11:51 +01:00
5098332d20 Restructuring 2025-01-29 18:11:39 +01:00
335a01d448 Changed Sum to use 2025-01-29 18:11:27 +01:00
61de673741 Corrected Color in Error Alert in Whitemode
Added Firstname and Lastname to Customer disabled when company
2025-01-29 18:10:59 +01:00
7ea5da8d0f Cahnges in Show Document 2025-01-27 18:14:43 +01:00
eb1eacdad9 Changes in Statement Allocation and Open Sum Calc 2025-01-27 18:14:33 +01:00
3188409bac Changes in Props 2025-01-27 18:14:03 +01:00
cbc1f5a84d Merge branch 'dev' into beta 2025-01-24 15:26:00 +01:00
6139f12e0d Cahgned Buttons 2025-01-24 15:25:40 +01:00
ce4efeaf2d Made Titel and Message Mandatory 2025-01-24 15:25:27 +01:00
7dcddba401 Changes in Dashboard Display
Added Project Card
Commented Graph Card
2025-01-24 15:25:16 +01:00
0bd894a61b Added Phases in Project Rendering 2025-01-24 15:24:53 +01:00
ab3437989a Merge branch 'beta' 2025-01-23 16:07:48 +01:00
540fe100cf Cahnged Base Url for Functions 2025-01-23 16:07:33 +01:00
b388f29df5 Merge remote-tracking branch 'origin/main' 2025-01-23 16:04:58 +01:00
b3f1295809 Merge branch 'beta' 2025-01-23 16:04:31 +01:00
80a465fad8 Added DP to Bankstatements 2025-01-23 16:04:01 +01:00
00e7e7e01e Rebuild Banking Integration to Function Server 2025-01-23 16:03:17 +01:00
43a28c9b2e Merge branch 'beta' into 'main'
Version 1.1.1

See merge request fedeo/software!4
2025-01-23 10:40:39 +00:00
06c775f563 Cahnged Ticket Creation 2025-01-22 18:32:02 +01:00
2f9bad0f8f Added Sort Column 2025-01-22 18:31:50 +01:00
ec9fae9e5a Added Sort Column 2025-01-22 18:31:39 +01:00
9efa596059 Changes in workingtimes 2025-01-21 09:54:05 +01:00
01914fcc1b Merge branch 'beta'
# Conflicts:
#	components/DocumentDisplay.vue
#	components/MainNav.vue
#	composables/useRole.js
#	composables/useSupabase.js
#	pages/createDocument/edit/[[id]].vue
#	pages/files/index.vue
#	pages/inventoryitems/index.vue
#	pages/services/[mode]/[[id]].vue
#	pages/vendors/[mode]/[[id]].vue
#	stores/data.js
2025-01-20 11:05:22 +01:00
33818033a4 Changes 2025-01-20 11:01:28 +01:00
e655d9cecd Cahngees in Cards 2025-01-20 11:00:52 +01:00
94d61a6d52 Changed usenextnumber from supabase to fs 2025-01-20 10:07:30 +01:00
830e5d3602 Introduced Functions Composable 2025-01-20 09:58:25 +01:00
ada3143ffb Removed Unused 2025-01-20 09:58:03 +01:00
879a8da1f4 Added Right Check to Kontakte
icon Changes
2025-01-20 09:57:56 +01:00
96a66f24e6 Tidying in Table 2025-01-20 09:57:33 +01:00
f6aae59e72 Corrected E-Mail link 2025-01-20 09:57:20 +01:00
9758c7b406 Removed DEV Output 2025-01-19 18:40:06 +01:00
bec94e4c6a Added Update Emit after Phase Change 2025-01-18 21:05:27 +01:00
e71281dcee Fixed Problems in LinkedDocuments and Storno 2025-01-17 18:49:19 +01:00
6626bd568d Added Function to Cancel Invoices 2025-01-17 17:26:59 +01:00
cdb3131185 Added E-Mail loading from Customer 2025-01-17 11:53:25 +01:00
57c0f81263 Added Archiving 2025-01-17 11:27:18 +01:00
b40553cc54 Changed NumberRange to EdgeFunction 2025-01-13 20:19:57 +01:00
62b29fb644 Changes in Evaluate 2025-01-13 11:27:36 +01:00
5555239fb3 Cahnges in E-Mail Creation 2025-01-11 19:04:24 +01:00
b2bc69f782 Changed Create Link 2025-01-11 18:59:39 +01:00
eff2b8a0bb Introduced UploadModal from Component 2025-01-11 18:59:22 +01:00
f2d4107172 Cahnges 2025-01-11 18:58:54 +01:00
0911678db0 Added own file for incominginvoice creation 2025-01-11 18:58:36 +01:00
120aa12727 Removed PWA Comment 2025-01-11 18:58:08 +01:00
f48bcdcd7b Removed Filetags 2025-01-11 18:57:56 +01:00
39b6ad28d0 Changes in Create New Item 2025-01-11 18:57:35 +01:00
2bd8b2b03a Changes in Document Display Modal 2025-01-11 18:57:05 +01:00
0d4d5227a0 Added DocumentUploadModal 2025-01-11 18:56:52 +01:00
07909550c3 Fixed Calendar 2025-01-11 18:54:04 +01:00
4f7bffe6fe Changed FileBucket 2025-01-11 18:53:47 +01:00
f3590ebf7c Changes 2025-01-11 12:41:02 +01:00
8b1950fc54 Changes 2025-01-11 12:29:15 +01:00
9a61a309a7 Changes 2025-01-11 12:25:13 +01:00
542f941879 Changes in DocumentDisplayModal.vue 2025-01-10 16:27:26 +01:00
c57ea6add6 Corrected key in checks 2025-01-10 16:20:56 +01:00
0d949c7894 Commented Own Fields 2025-01-10 16:19:02 +01:00
f6accf0aa7 Changes 2025-01-10 15:52:49 +01:00
1ecf89a2b1 Added Search to materialComposing.vue 2025-01-10 14:15:50 +01:00
630d04fb46 Added Sorting to createddocument Loading 2025-01-10 14:15:39 +01:00
8a00dffce0 Added CustomerRef to HistoryItemGen 2025-01-10 14:15:22 +01:00
423733967e Added Loading for DeliveryDate 2025-01-10 14:15:06 +01:00
38c6e01d9f Added Customer Ref
Added Document Error in createddocuments
2025-01-09 11:50:13 +01:00
566efb0d2c Added Trailing to Datatypes
Added Description Loading in LinkedDocument
2025-01-09 11:31:26 +01:00
06725ee497 Corrected Setting Error for Product in createddocument 2025-01-08 10:03:40 +01:00
4df416a818 Corrected Error in Dashboard 2025-01-07 16:57:34 +01:00
26fef320ef Corrected Errors in Workintimes
Introduced Error Logging to Supabase
2025-01-07 16:43:24 +01:00
ff1685a721 Added rounding and total calc to materialComposing.vue 2025-01-07 15:36:12 +01:00
0baba63542 Added MaterialComposition
Added Service Categorie Rendering
2025-01-07 15:25:02 +01:00
2c175ad1b2 Removed logs 2025-01-07 14:46:29 +01:00
cd190132f9 Fix in Filters 2025-01-07 14:29:44 +01:00
0bab558c75 Updated in Files and Archiving 2025-01-07 12:42:00 +01:00
af38afc5b5 Added Reloaded after File Upload
Change selection for Images
2025-01-07 12:03:14 +01:00
96184e4853 Fixed Document Upload 2025-01-07 11:22:03 +01:00
46fb5de260 Added tenant log when no role is Present 2025-01-07 11:21:55 +01:00
ceed45e409 Added Filters for Archived 2025-01-07 11:21:37 +01:00
8d9aed0ee1 Added Drafts
Tidying in displayOpenBalances.vue
2025-01-07 10:28:28 +01:00
308e9629b5 Corrected Event Handler for ContactPerson 2025-01-07 10:17:28 +01:00
778308940a Corrected absencerequests
Corrected RecreationDays to 2025
2025-01-07 10:17:03 +01:00
5ee5e671e7 Added start/enddate rendering 2025-01-07 10:16:36 +01:00
7f23d8efd8 Added File Moving 2025-01-05 22:11:42 +01:00
639cdb4c1f Added File Moving 2025-01-05 21:59:04 +01:00
3a4b1a7a56 Corrected Tabs 2025-01-05 21:16:31 +01:00
c103e9402a Corrected Show File Modal 2025-01-05 21:16:13 +01:00
a326c6ab3a Fix in Calendar 2025-01-05 21:15:51 +01:00
efbb97967a Many Changes 2025-01-05 18:23:44 +01:00
1c6c6e4a33 Corrected 2025-01-03 11:01:06 +01:00
159b77334b Corrected 2025-01-03 10:50:20 +01:00
cae33c92c9 Added Scroll to createDocument Show 2025-01-03 09:32:49 +01:00
cbdf3edd8d Added Birthday & EntryDate 2025-01-03 09:32:32 +01:00
8723540b0d Added GetAvailableStringVars 2025-01-02 19:23:31 +01:00
4f395a01d3 Added Link to MAWEBFORM Only for Tenant 21 2025-01-02 19:08:14 +01:00
b877d5f91b Changes in Timetracking
Added Lieferscheine Button to EntityShow
DataType Changes
Fixed Loading Errors in createDocument
Added Telephone to profile show
2025-01-02 14:04:55 +01:00
595531683b Fixed Calendar Link 2024-12-31 23:56:54 +01:00
6989dd61f7 Fixed Calendar & Timeline
Fixed AbsenceRequest Manual Selects
2024-12-31 23:40:12 +01:00
4ef7d410f4 Changes 2024-12-31 18:02:15 +01:00
cacdb442ca Fixed Invoicing Problem and some other Changes 2024-12-31 16:07:15 +01:00
9a70879778 Changes 2024-12-30 11:22:58 +01:00
d5ef6469bd Changes 2024-12-30 10:44:55 +01:00
f44ac5960c Changes 2024-12-30 10:44:30 +01:00
803b155f65 Changes 2024-12-30 10:35:20 +01:00
a55d4817bd Changes in CreatedDocuments Edit 2024-12-30 09:32:44 +01:00
da3dc1e663 DataType Changes 2024-12-30 09:31:28 +01:00
9884a08e83 Tidying in Document Display 2024-12-30 09:31:03 +01:00
cd463bd1d1 Added Billing to Nav 2024-12-30 09:30:47 +01:00
ee5ebfe0b9 Changes in Standard Entity Components 2024-12-30 09:30:30 +01:00
92ec684066 Added Rendering Components 2024-12-30 09:30:14 +01:00
4dcce6238f Fixed Profile Edit 2024-12-28 14:44:07 +01:00
98619a9082 Fixed Profile Edit 2024-12-28 14:41:50 +01:00
334ee2f897 Removed Big Comment 2024-12-28 14:34:25 +01:00
156ca348aa Tidying and Datatype Changes 2024-12-28 14:34:07 +01:00
8cfa5eaa43 Cleared Deprecated Folder 2024-12-28 14:33:36 +01:00
d3c865a10f Minor Changes 2024-12-27 12:22:37 +01:00
42686efbe7 Added PLZ Autocompletion & InputChangeFunctions 2024-12-27 12:14:27 +01:00
a1e6061579 Fixed Creation Error 2024-12-27 11:37:32 +01:00
2bda15d264 Deprecated Events as non Standard Entity
Repaired query
Reparied Document Show
2024-12-27 11:05:59 +01:00
43c7148637 Removed Deprecated Components 2024-12-27 11:04:07 +01:00
1a79f9dbd9 Deprecated absencerequests as non Standard Entity
Added Respective Rights
Changes to show title
2024-12-25 17:00:09 +01:00
325d25034d Minor Changes, Tidying, Removed Module Google Fonts 2024-12-25 16:21:55 +01:00
4a0e092115 Deprecated following as non standardEntity checks, inventoryitems, spaces 2024-12-25 16:21:22 +01:00
1ba3d9c3e9 Deprecated following as non standardEntity tasks, products, productcategories, services, servicecategories 2024-12-22 22:13:34 +01:00
61110da453 Introduced EntityEdit.vue
Introduced EntityShow.vue

Deprecated following as non standardEntity contracts, customers, vendors, projects, plants, vehicles
2024-12-22 17:00:21 +01:00
565d531376 Introduced EntityEdit.vue
Introduced EntityShow.vue

Deprecated following as non standardEntity contracts, customers, vendors, projects, plants, vehicles
2024-12-22 16:59:18 +01:00
b465f4a75a Introduced ProfileStore
Corrected All Links to DataStore
2024-12-21 22:33:42 +01:00
813944fc23 Changes in Rights and Roles 2024-12-21 18:53:53 +01:00
c8521ad1f6 Reparied Cancel Button 2024-12-20 20:00:23 +01:00
0d849f5fcb Reffractored vendors,vehicles,services,servicecategories,products,productcategories, projects, plants, customers, contracts, contacts 2024-12-20 20:00:08 +01:00
8abfce0fa1 Revert "Start for Dev Branch"
This reverts commit acf5d1c2ea
2024-12-20 17:49:24 +00:00
acf5d1c2ea Start for Dev Branch 2024-12-20 18:46:52 +01:00
a6c1eaf69f Changed users to profiles in projects 2024-12-18 20:47:01 +01:00
756bfb8478 Introduced EntityList.vue and implemented it in projects 2024-12-18 20:46:28 +01:00
1af63705ff Updated vue & nuxt 2024-12-18 20:44:20 +01:00
9e02e1f99d Fixed Error in Working Times Display 2024-12-18 08:35:29 +01:00
05a4ecc654 Change in Table Expansion 2024-12-11 21:56:05 +01:00
847d8512e7 Updated Nuxt Ui 2024-12-11 20:59:43 +01:00
6b8bf96bec Added Bank Account Updating 2024-12-11 20:47:19 +01:00
586a2f5fc1 Added Bank Account Updating 2024-12-04 10:45:41 +01:00
ff5d20421e Added Checks
Added Documents to Inventoryitems and Checks
2024-12-01 23:10:34 +01:00
8e68858489 Added Christmas Logo 2024-12-01 13:44:55 +01:00
a6712f7c98 Changes 2024-12-01 13:44:38 +01:00
9993217ed1 Corrected Errors in Document Creation 2024-11-25 19:43:57 +01:00
5928c34b03 Added Button for DeliveryNote Invoicing 2024-11-21 21:56:27 +01:00
5817931099 Added Shoe Size to Profile 2024-11-21 21:56:07 +01:00
024adba069 Update file [[id]].vue 2024-11-21 20:35:23 +00:00
c093f9d191 Some Changes 2024-11-21 21:28:29 +01:00
60658a2ef9 Added Agriculture
Removed Prices for Delivery Notes
2024-11-21 21:27:40 +01:00
3633b8ee37 Some Changes 2024-11-20 23:00:43 +01:00
46ddd5659b Some Changes 2024-11-20 22:55:55 +01:00
f9ab8f4050 Some Changes 2024-11-20 22:42:13 +01:00
4b6857958c Some Changes 2024-11-20 22:33:16 +01:00
d9a22518da Some Changes 2024-11-20 21:23:15 +01:00
818bfd5b1c Some Changes 2024-11-20 21:10:20 +01:00
fbf1f78d64 Added Chats 2024-11-20 21:08:50 +01:00
59424f067c Removed Edit button when document is finished 2024-11-20 13:49:16 +01:00
869f381a1b Introduced New Projecttypes and Phase Display 2024-11-20 13:48:13 +01:00
988c33d07d Tidying in Product Page 2024-11-20 13:45:18 +01:00
fc9984eb3a Added Fields to Vehicles 2024-11-20 13:44:54 +01:00
ce4a6fcd67 Removed WorkingTimeEvaluation in Profile Page
Added Document Upload to Profile
2024-11-20 13:44:32 +01:00
60c2870123 Added TODO 2024-11-20 13:43:41 +01:00
1c15f02d34 Removed Unused Tabs 2024-11-20 13:43:20 +01:00
0140ffaf5e Added Projecttypes 2024-11-20 13:42:12 +01:00
2899633436 Added UUID Package 2024-11-20 13:41:50 +01:00
9812c0a122 Moved Selection for Letterhead 2024-11-20 13:41:36 +01:00
947fe710a3 Added Agriculture Module to Invoice Creation 2024-11-13 19:13:45 +01:00
a246263424 Added Notifications
Added Mentions in HistoryItems
2024-11-08 20:18:50 +01:00
f69b30b5ba Added Notifications
Added Mentions in HistoryItems
2024-11-08 20:17:56 +01:00
928e4d0ca9 Moved Dark Mode 2024-11-08 18:56:41 +01:00
45a81d90df Moved Dark Mode 2024-11-08 18:54:42 +01:00
27ccfd2c72 Some Tidying 2024-11-08 18:42:42 +01:00
a61382486f Added Archiving & Some Tidying in Vehicles 2024-11-08 18:38:54 +01:00
c67c4a70c4 Added Archiving 2024-11-08 18:19:50 +01:00
53b59bd95f Integration of MS365 Login into Login 2024-11-08 17:45:34 +01:00
3a55c80ae2 Tidying in Plants 2024-11-08 17:45:14 +01:00
34533b401c Change in Numberranges of data type 2024-10-29 15:58:35 +01:00
ecf7110781 Changes in Workingtimes 2024-10-29 15:53:59 +01:00
d3a7f0636b Changes in text templates 2024-10-20 16:34:45 +02:00
13c91fe728 Changes in Times Evaluation 2024-10-20 16:28:28 +02:00
d3c2c8f642 Changes in Times Evaluation 2024-10-20 16:14:01 +02:00
a905b1f966 Changes 2024-10-18 08:58:11 +02:00
8dbf43b672 Changes in Contact Request 2024-10-08 17:22:55 +02:00
ca15cfbd0b Changes 2024-10-08 16:08:30 +02:00
2cbc30de6f Changes 2024-10-08 14:30:52 +02:00
163c6232b8 Changes 2024-10-08 14:30:11 +02:00
3efbd9065a Changes 2024-10-08 14:12:04 +02:00
7fb9744847 Cahnges 2024-10-08 13:57:23 +02:00
06badd590c Added Email-Signature to Profile 2024-10-08 13:53:36 +02:00
e1f94cfb72 Changes 2024-10-08 13:37:03 +02:00
16932ad71c Changes 2024-10-08 13:08:13 +02:00
856628bce6 Fixed #51 2024-10-06 13:20:41 +02:00
1e1f82cc2d Added Searching in Service & Product Selection
Introduced Service Categories
2024-10-05 12:28:56 +02:00
0f92dbe61c Standard BCC in E-Mail 2024-10-01 13:48:52 +02:00
42bfb2d8eb Changed Search Function 2024-10-01 13:06:21 +02:00
f461bb7694 Tidying 2024-10-01 13:06:10 +02:00
da62213579 Added E-Mail Sending 2024-09-30 18:49:43 +02:00
c1282c613e Added E-Mail Sending 2024-09-30 18:34:33 +02:00
782f97afcc Added E-Mail Sending 2024-09-30 18:34:16 +02:00
a75506b183 Some Serial Invoice
Free Text Pos
Minor Changes
2024-09-29 19:17:26 +02:00
5d7714519a Pushed Serial Invoices 2024-09-29 19:02:35 +02:00
082573f6d9 Added Document Linking
Minor Changes in Document Creation
2024-09-29 17:57:38 +02:00
ffea7627cf Rendering Corrections 2024-09-29 11:40:03 +02:00
f9995505a8 Help Slideover and trackingtrips 2024-09-27 21:12:47 +02:00
f31e76ac3a Help Slideover 2024-09-27 13:02:45 +02:00
2458b3573f Some Changes in Pos Numbering 2024-09-26 18:56:19 +02:00
3c5f80f8b5 Some Changes in Pos Numbering and Problem Display 2024-09-26 18:42:17 +02:00
eee6060e58 Added Error Blocking in Invoice Creation 2024-09-25 19:38:00 +02:00
b0f186dc4e Added Error Display in Invoice Creation 2024-09-25 19:35:22 +02:00
db3880a31a Minor Changes 2024-09-25 19:30:55 +02:00
673bcb279a Added Scrollcontainer 2024-09-25 19:29:35 +02:00
805ed8e9f4 Changes in Layout 2024-09-22 14:14:02 +02:00
51dbb10b45 Changes in Tracking and some changes in general historyitems 2024-09-22 14:10:04 +02:00
516bf5dd7f Pushing Tracking 2024-09-22 12:09:39 +02:00
fc0a6eaa76 Minor Changes in InventoryItems 2024-09-20 12:28:04 +02:00
93a2d96c21 Minor Changes in Invoice Creation 2024-09-19 19:34:41 +02:00
c546e2cf3c Added Productcategories 2024-09-18 20:00:12 +02:00
1e4d0153b4 Letterhead Change & Minor Changes in Doc Creation 2024-09-16 19:07:51 +02:00
d5c2ed86f7 Changes 2024-09-14 17:22:07 +02:00
c70b172b08 Changes 2024-09-14 17:09:29 +02:00
6f965b1704 added allocating for more than one bankstatement 2024-09-06 21:15:26 +02:00
9cad48cb31 Started open stuff card 2024-09-06 21:15:00 +02:00
5a8d8fd5a9 Bug Fixe in Invoice Date 2024-09-06 20:10:54 +02:00
acd8fc8290 Implemented Document Folders 2024-09-06 12:16:50 +02:00
c8265aebea QUick fixes in inventoryitems 2024-09-06 09:43:02 +02:00
ab7df093c4 Added Umami 2024-09-03 11:40:37 +02:00
876c8774fa Minor Changes 2024-08-30 18:36:18 +02:00
26f8d8f710 Restructuring in Project Page
Added Project Number
2024-08-29 22:31:34 +02:00
133fd1d892 Reactivated Phases 2024-08-29 20:43:15 +02:00
60a860d9b5 Tidying 2024-08-28 21:49:51 +02:00
725fe01b69 Change to Edge Functions 2024-08-28 21:39:29 +02:00
3b8aeb3b87 Changes 2024-08-27 17:27:58 +02:00
22d99ba39e Changes 2024-08-26 18:34:54 +02:00
5e4118acdd Changes 2024-08-25 20:46:59 +02:00
734c9ec8f3 Added Chart to HomeScreen 2024-08-25 20:45:52 +02:00
4127c6d4fb Added HistoryItems to Spaces
Changed Loading of HistoryItems to directly Supabase
Minor Changes in inventoryitems
2024-08-23 17:39:42 +02:00
b71814369d Light Restructuring 2024-08-23 12:09:53 +02:00
1c76d8e63c Changed Notification Position 2024-08-23 12:09:35 +02:00
7457abb173 Added Title to Document Creation
Added Height Calc for Row Description
2024-08-22 19:48:11 +02:00
a349b1eb4f Changed Listing in Spaces Index 2024-08-22 19:12:18 +02:00
0bc0a59939 Changed Listing in Spaces Index 2024-08-21 19:10:00 +02:00
75963ce8b4 Added Space Type "Standort" 2024-08-21 19:04:29 +02:00
db096e462c Added Numberrange to inventoryitems 2024-08-10 16:30:43 +02:00
9846e91c2f Changes in Numberranges 2024-08-10 14:39:26 +02:00
98d14a3e34 Changed NumberRange Structure to Tenant JSON Column 2024-08-10 14:25:56 +02:00
4ded159c49 Cahnges in Invoice allocation in statements 2024-08-09 11:52:11 +02:00
baa06b60fb Cahnges 2024-07-30 12:01:07 +02:00
c776100ed0 Removed Draft Filtering
Changed Invoice Sorting
2024-07-22 11:01:20 +02:00
8f7cfe8362 Added Page Title 2024-07-21 22:57:42 +02:00
d915cce277 Added Highlighting for Accordions 2024-07-21 22:53:17 +02:00
d31478a858 Corrected Scrollbar 2024-07-21 22:48:20 +02:00
dc480f38b6 Changes in Tags and Updating 2024-07-21 22:34:10 +02:00
510ce73ecd Corrected Minor Issues with Taxing 2024-07-21 22:33:27 +02:00
91bc893001 Remodeled MainNav with an extra component 2024-07-21 22:32:46 +02:00
269c5f4b59 Restructured Pages
Added parent Spaces
2024-07-20 14:50:58 +02:00
013ae3c69c Added Quantity to Invetoryitems 2024-07-17 10:27:20 +02:00
de327850ae Added Quantity to Invetoryitems 2024-07-17 10:20:16 +02:00
53000988d9 Changed Docker Loading 2024-07-14 21:52:26 +02:00
02beb31e43 Changed Docker Loading 2024-07-14 21:27:29 +02:00
c27fd4cd2d Changes 2024-07-14 21:26:46 +02:00
fc0caf2d00 Changes 2024-07-12 22:20:45 +02:00
d01869fca8 Many Changes 2024-07-12 22:05:48 +02:00
1e952e008e Some Changes in Projects 2024-07-10 21:22:24 +02:00
f9909a87aa Changes in Events
Changes in Times
2024-07-10 21:10:39 +02:00
dc3c8a2b60 Some Changes 2024-07-09 21:53:11 +02:00
eb4b8a8d9b Some Changes 2024-07-09 21:35:19 +02:00
101b8d3361 Added Styling to Balance in Account Table 2024-07-04 19:04:34 +02:00
669f50de6c Changed Bas URL 2024-07-04 18:28:10 +02:00
10c6e72d87 Changes in Texttemplate Creation 2024-07-03 14:23:32 +02:00
d327277bac Changes 2024-07-02 18:38:11 +02:00
d2da96eaa3 added clothing size to Profile Page 2024-07-02 18:19:52 +02:00
e8b75956d0 added articleNumber to barcode input 2024-06-14 17:23:09 +02:00
de1fe083d8 added column 2024-06-14 17:00:44 +02:00
de70c4ca80 Changed Toast Position to Bottom Right 2024-06-10 19:26:04 +02:00
bc24f49476 Many Changes in Navigation, Shortcuts, Search and Data Pulling directly from Supabase 2024-06-05 14:34:23 +02:00
e139eb771c Changes 2024-06-02 21:39:26 +02:00
4cd4a9c7c4 Added Contract to Document Assign 2024-05-31 11:18:10 +02:00
26d0148525 Added Contract to Document Assign 2024-05-23 10:31:07 +02:00
eca1cd380b Changes 2024-05-23 10:27:52 +02:00
28ff274107 Many Changes 2024-05-13 10:43:23 +02:00
491d502c40 Many Changes 2024-05-10 22:41:32 +02:00
7966173385 Added Reset in Inventory
Added Keyboard Controls for Tab Nav and Back to List
Added Select On Enter for First Entry in Search

for Customers and Vendors
2024-05-01 21:55:41 +02:00
86cd55102c Changed layout for Vendors 2024-05-01 09:52:33 +02:00
7a337482d4 Changed layout for Vendors 2024-05-01 09:16:43 +02:00
1cbb8cbacf Rebuild Inventory
Added Advance Invoices
2024-04-23 20:28:26 +02:00
633d75b798 Changed Rendering of IncomingInvoice when not in editing 2024-04-16 18:13:49 +02:00
ac9fadf922 Some Changes in E-Mail Page 2024-04-16 18:01:46 +02:00
eddaae2d87 Restructured IncomingInvoices
Added Aspect Ration to DocumentDisplay.vue
2024-04-16 18:00:35 +02:00
1269d3b838 Added ProfileSelection when no profile is selected 2024-04-16 11:34:13 +02:00
c1108314c1 Moved Buchhaltung 2024-04-16 11:33:55 +02:00
0fd9db2357 Added More Features to Disable 2024-04-16 10:59:55 +02:00
aa322a3234 Fixed Adress Loading when customer is preset
Added more Display Options
Enabled Timeline in Devtools
Changed Style of Document Display
2024-04-16 10:51:33 +02:00
34dfb334ec Added TextTemplates Page and Function 2024-04-14 21:54:23 +02:00
f9d7c93d21 Changed typo in absenceRequests 2024-04-11 13:41:48 +02:00
6114c96b14 Changed filteredRows 2024-04-11 12:09:08 +02:00
bb158c1353 Added Automatic ZIP Completion 2024-04-10 11:14:57 +02:00
bf04b9c563 Changes 2024-04-10 10:09:56 +02:00
9fa1059301 Changes 2024-04-08 21:33:10 +02:00
0f7555907b Added Automatic HistoryItems to more DataTypes 2024-04-08 21:04:32 +02:00
ca62d492ba Changes in CI/CD
Added Entries to HelpSlideover.vue
Removed Chip Display from index notifications bell
2024-04-08 15:42:05 +02:00
44a0e10a94 Added Automatic HistoryItems to Events,Customers,Vendors 2024-04-08 15:41:28 +02:00
3a0f3f75b4 Changed Notifications to Benachrichtigungen
Correcte getStartetWorkingTimes Functions
2024-04-08 13:06:11 +02:00
e2a15644ce Added Event Table to projects
Added Notes to Vendors
Added Notes and Link to Event
2024-04-08 09:37:04 +02:00
129c0e4d25 Lösche .DS_Store 2024-04-07 20:27:25 +00:00
2fe1aeb4f2 Restructured Project Rep 2024-04-07 22:26:47 +02:00
d51ad2c4eb Restructured Project Rep 2024-04-07 22:25:16 +02:00
895f508c29 Changes 2024-04-07 19:10:17 +02:00
e0750e755f Restructured Workingtimes without date to start and end
Added Page to Edit Workingtimes
2024-04-07 18:26:14 +02:00
491cbf15b6 Changes 2024-04-07 17:18:58 +02:00
d7fafda78e Added Page Events
Added WeekNumbers to DatePicker
Changed Coloring in DatePicker
2024-04-07 14:21:14 +02:00
092f3aa6bd Added Business Info Editing 2024-04-07 12:55:56 +02:00
281f3562ec Added Content to HelpSlideover
Added Shortcut to Settings
Added Feature Disabling Settings to tenant.vue
2024-04-07 12:44:23 +02:00
7c162f157a Added Feature disabling for some Features 2024-04-07 12:21:06 +02:00
e4b02af524 Removed unnecessary console.log 2024-04-07 12:05:07 +02:00
cd79725a27 Changed Sorting in Profiles to Lastname
Added Index Card check for Anwesenheiten
Added Type Sorting to Receipts list
2024-04-07 12:04:36 +02:00
88bca67745 Changes 2024-04-01 17:36:31 +02:00
c0e0345faa Changes 2024-03-19 13:59:11 +01:00
34096f877a Changes in times and Dashboard 2024-03-19 13:13:41 +01:00
66ee33cdde Changes in times and Dashboard 2024-03-19 12:26:16 +01:00
edf1de189b Changes 2024-03-19 10:23:57 +01:00
d4edc66c2c Changes 2024-03-18 21:20:23 +01:00
6ef8573032 Changes 2024-03-18 20:50:20 +01:00
e4a41d9126 Changes 2024-03-18 10:22:11 +01:00
39a2f19b0d Changes in workingtimes.vue 2024-03-18 09:10:18 +01:00
73d3c6311a Changes in Document Creation 2024-03-17 12:14:11 +01:00
aef8cce755 Remodel of Profile System
Added isCompany to Customers
changes in workingtimes.vue
2024-03-17 11:01:19 +01:00
874ff01551 Changes 2024-03-14 08:13:05 +01:00
d1419fdad1 Added Zahlungsziel 2024-03-13 08:37:37 +01:00
85dd60c197 Added Fullname to Contact Creation 2024-03-12 19:09:03 +01:00
6791342879 Changes 2024-03-12 13:38:24 +01:00
423b2638aa Changes 2024-03-11 15:07:18 +01:00
99b8738c31 Changes 2024-03-11 14:51:13 +01:00
62b5e1bc57 Changed E-Mail Field
Changes
2024-03-07 11:53:41 +01:00
5783fb1f2e Changes 2024-03-07 11:26:18 +01:00
5cbfbff4ac Changes 2024-03-07 11:04:58 +01:00
1cbea757d0 Changes 2024-03-07 10:32:47 +01:00
fb8041c32e Changes 2024-03-04 22:19:37 +01:00
8f444bd917 Changes in Document Creation, Calendar, Notifications, Settings 2024-03-04 20:26:30 +01:00
8e69cda09b Changes 2024-03-03 20:38:59 +01:00
b4b70d8e7c Changes 2024-03-01 22:48:03 +01:00
3924fd79d2 Changed to new Layout System 2024-02-23 22:34:39 +01:00
0d86e4c4f9 Changed to new Layout System 2024-02-23 19:30:43 +01:00
96d4ee7356 Rebuild General Layout to Nuxt UI PRO Dashboard 2024-02-22 22:23:15 +01:00
c6e0854544 Changes 2024-02-22 19:01:12 +01:00
4e3ac183d4 Corrected Incoming Invoice
Added Column Selection to Customers,Vendors and Contacts
2024-02-22 17:29:33 +01:00
436cb2c163 Changes 2024-02-21 16:53:54 +01:00
ddb3b90788 Changes 2024-02-21 16:38:48 +01:00
6e2e419a1c Changes 2024-02-19 22:25:58 +01:00
d5c3034758 Added Italien 2024-02-19 15:58:56 +01:00
0ccd5635e7 Included Tenant Value in Creation
Added Fields to Customer Info Data
2024-02-19 15:49:04 +01:00
0495f40bef Changed Dockerfile to index.mjs 2024-02-19 08:21:30 +01:00
630798c89f Many Changes 2024-02-19 07:46:28 +01:00
fa0eb73363 Many Changes 2024-02-18 19:51:00 +01:00
1a0b7288df Added Phases to Projects 2024-02-15 22:49:09 +01:00
2fc45b3ea0 Added Phases to Projects 2024-02-05 20:48:15 +01:00
22a3b8698c Corrected Loading error 2024-02-04 20:43:45 +01:00
fa661ff6b3 Many Changes for 1.0 2024-02-04 20:21:09 +01:00
bd09d07698 Many Changes 2024-02-01 22:17:56 +01:00
34d1eb9c71 Many Changes 2024-02-01 21:00:59 +01:00
fe74e7d91b Changes in RLS and Tenants
Many Changes in Invoice Editor
Page Loading Rebuilt
Started Rights Management
2024-01-30 21:18:46 +01:00
3167b6a20a Changed Plants to Objects
Changes in outgoinginvoices
2024-01-27 11:54:14 +01:00
6f6e835b0a Added HistoryDisplay to IncomingInvoices 2024-01-16 21:41:35 +01:00
497d768d4e Restructured Update Process Into Store 2024-01-15 21:54:12 +01:00
9f5a142680 Restructured Create Process Into Store 2024-01-15 19:50:26 +01:00
f6c1f4219b Changed TimeGrid 2024-01-15 12:28:53 +01:00
f5e7700809 Added Chat
Restructured Calendar
Some Changes in Timetracking
2024-01-15 10:19:06 +01:00
05130052af Added HistoryDisplay.vue to Projects and Plants
Visual Restructure in Plants
2024-01-12 18:38:26 +01:00
291b0350e8 Build Profile View with Times View and some Profile Editing
Some Changes in timetracking.vue
2024-01-12 18:21:53 +01:00
7aa06f595d correted Error with new Time Creation
made Times Editable
created field for user filter
2024-01-12 17:01:45 +01:00
3227414a92 added expense field to incominginvoice 2024-01-11 18:40:28 +01:00
12323382a5 many changes 2024-01-11 18:33:56 +01:00
d62fc5d668 Changed DayJS Namespace 2024-01-05 18:24:58 +01:00
8822854040 Changed DayJS Namespace 2024-01-05 18:17:50 +01:00
61793838bb Many Changes
Introduced Plants
Some Polishing
Some Resources got Query Params
Extended GlobalSearch.vue
Removed Jobs
2024-01-05 18:06:09 +01:00
991cac18f2 Many Changes 2024-01-04 12:27:46 +01:00
57e856c71c Store change rest 2023-12-27 22:11:41 +01:00
c41b99f29d Changed STore Type and corrected all Pages
Added HistoryDisplay.vue
Added NumberRanges
2023-12-27 21:52:55 +01:00
9e092823e4 Added Vehicles
Added Bankimport, BankAccounts, BankStatements
Some Visual Changes
Added Contacts
Changes in VendorInvoices
Added layouts with default an one for Login PAge
Added Input Group Component
2023-12-22 17:50:22 +01:00
8a1e2384d1 Corrected Imapsync
Added different Tags feature to imapsync
2023-12-22 10:38:30 +01:00
8d777a3d50 Removed vue-barcode-reader import 2023-12-21 16:20:35 +01:00
3625db30ec Corrected Empty Slot for Tables 2023-12-21 16:17:43 +01:00
1573cb2b1e Some Tests 2023-12-21 16:05:22 +01:00
537896503f Some Changes 2023-12-21 16:05:13 +01:00
e792ed39c9 Changed Tasks List
Created Time creation
Added VueDatepicker Package
2023-12-21 16:04:52 +01:00
cc636ce040 Removed Vue Barcode Reader 2023-12-19 15:18:18 +01:00
c82a0e5e1c Document Restructure
Introduced ExternalDevices Settingspage
Added DocumentDisplay.vue Component
Some Changes to Spaces
2023-12-18 19:43:50 +01:00
b9772def05 Many Changes 2023-12-15 20:48:47 +01:00
0590fa0875 Tests with PDF library 2023-12-14 20:59:44 +01:00
cd36514e1c Added DayJS
Restructured Products
Some Changes in Documents
Some Changes with Logo
2023-12-14 20:58:52 +01:00
2dd31690e5 Added New Viewport Config 2023-12-11 20:30:10 +01:00
2721a3b2d4 Changes Logos 2023-12-11 12:23:39 +01:00
5503c572f1 Added Logo
Added Document Download
Added zipjs
2023-12-11 12:04:32 +01:00
6ffc4f01d9 Color Changes
Login Changes
Misc
2023-12-10 15:06:16 +01:00
5182959881 Rebuild Times in Projects
Added Icons
Rebuild Time Duration
2023-12-07 12:14:19 +01:00
36371f94e8 Some Changes in TimeTracking and boosting Mobile View 2023-12-06 22:26:36 +01:00
2b7bf12bc7 Removed Dev Flag from PWA Module 2023-12-06 22:07:14 +01:00
ce3a013f86 Changed Customers to Multi Page with Route Params to add mobile performance 2023-12-06 22:06:57 +01:00
987f8a0bec Changes to Timetracking 2023-12-05 22:35:25 +01:00
73678f0507 Changes to Timetracking 2023-12-05 22:18:30 +01:00
0d6357af26 Changes to PWA 2023-12-05 14:24:25 +01:00
e863bea269 Added PWA 2023-12-05 13:30:16 +01:00
6d13d02efb Changed Software Name 2023-12-04 20:52:45 +01:00
6a5238d2bb Changed Software Name 2023-12-04 20:50:09 +01:00
76aa6631f3 Readded Progress Bar 2023-12-04 20:48:13 +01:00
4b413e0209 Added Reset after Creation & Save for Customers 2023-12-04 20:40:33 +01:00
04f4ccbe03 Added Nuxt UI Pro License 2023-12-04 20:30:15 +01:00
ef9105e286 Changes 2023-12-04 20:24:01 +01:00
68a5775717 Removed Name from documents
Added Customers Reload
2023-12-02 17:33:33 +01:00
fb6e8a89c0 Merge remote-tracking branch 'origin/main' 2023-12-02 17:12:51 +01:00
999738ed4b Changed Dockerfile 2023-12-02 17:12:43 +01:00
Florian Federspiel
19401d27c0 Delete package-lock.json 2023-12-02 16:11:40 +00:00
465a531bf4 added package-lock.json 2023-12-02 17:09:48 +01:00
Florian Federspiel
5da6b4ae99 Merge branch 'bryntum' into 'main'
Implemented Fullcalendar

See merge request cmykmedia/spaces!1
2023-12-02 16:07:38 +00:00
f63bda171f Implemented Fullcalendar 2023-12-02 17:06:39 +01:00
45da05c9a4 Changes 2023-12-02 13:09:23 +01:00
098bc97fa4 Added Nodemon to IMAPSYNC 2023-11-29 19:58:21 +01:00
d74d7abc90 Added Dockerfile and CI/CD for Imapsync
Added Core Functionality for Imapsync
2023-11-29 19:52:37 +01:00
ff966418b2 Removed Bugs 2023-11-28 08:13:21 +01:00
7cc942b42f Removed Tenant from Dropdown 2023-11-26 17:45:09 +01:00
dea4f7eddc Changed Backend to Supabase 2023-11-26 17:38:37 +01:00
cb3d48d42c Changed Backend to Supabase 2023-11-26 17:15:55 +01:00
8b76434b41 Added Vue-PDF to Spaces 2023-11-25 17:29:13 +01:00
2ed3ed4b45 Added Dockerfile 2023-11-25 17:24:17 +01:00
f400833213 New changelist 2023-11-25 17:12:19 +01:00
Florian Federspiel
832a0b9f29 added ci 2023-11-25 17:00:33 +01:00
Florian Federspiel
677030f712 Initial 2023-11-25 16:53:52 +01:00
1065 changed files with 320398 additions and 1 deletions

10
.dockerignore Normal file
View File

@@ -0,0 +1,10 @@
.git
**/node_modules
**/.nuxt
**/.output
**/dist
**/.env
**/.env.*
!**/.env.example
.release
gmail-puett

128
.env.example Normal file
View File

@@ -0,0 +1,128 @@
# FEDEO Selfhosting
# Feste Release-Version, z. B. 3.0.0. dev behält den bisherigen Entwicklungskanal bei.
FEDEO_VERSION=dev
DOMAIN=app.example.com
CONTACT_EMAIL=admin@deine-domain.de
DB_NAME=fedeo
DB_USER=fedeo
DB_PASSWORD=change-this-db-password
DATABASE_URL=postgres://fedeo:change-this-db-password@db:5432/fedeo
MINIO_ROOT_USER=fedeo-minio
MINIO_ROOT_PASSWORD=change-this-minio-password
MINIO_BUCKET=fedeo
HOST=0.0.0.0
PORT=3100
FEDEO_RUN_MIGRATIONS=true
COOKIE_SECRET=change-this-cookie-secret
JWT_SECRET=change-this-jwt-secret
ENCRYPTION_KEY=change-this-encryption-key
MAILER_SMTP_HOST=smtp.example.com
MAILER_SMTP_PORT=587
MAILER_SMTP_SSL=false
MAILER_SMTP_USER=mailer@example.com
MAILER_SMTP_PASS=change-this-mail-password
MAILER_FROM=FEDEO <no-reply@example.com>
# Desktop Push per Web Push. Schlüssel können mit
# `npx web-push generate-vapid-keys` erzeugt werden.
WEB_PUSH_PUBLIC_KEY=replace-this-web-push-public-key
WEB_PUSH_PRIVATE_KEY=replace-this-web-push-private-key
WEB_PUSH_SUBJECT=mailto:admin@example.com
S3_ENDPOINT=http://minio:9000
S3_REGION=eu-central-1
S3_ACCESS_KEY=fedeo-minio
S3_SECRET_KEY=change-this-minio-password
S3_BUCKET=fedeo
# Datei-Backend. S3 bleibt aktuell der Standard; Seafile kann als externer
# Dateidienst angebunden werden, sobald der Backend-Umbau aktiviert ist.
FEDEO_FILE_BACKEND=s3
# Externer Seafile-Dienst, nicht Teil des Standard-Compose-Stacks.
SEAFILE_BASE_URL=https://files.example.com
SEAFILE_INTERNAL_URL=https://files.example.com
SEAFILE_ADMIN_EMAIL=admin@example.com
SEAFILE_ADMIN_PASSWORD=change-this-seafile-admin-password
M2M_API_KEY=change-this-m2m-key
API_BASE_URL=https://app.example.com/backend
# Collaboration uses API_BASE_URL for federation and its origin for guest links.
# Optional overrides only, e.g. when using a separate federation gateway.
FEDEO_PUBLIC_URL=
FEDEO_FEDERATION_URL=
# auto: enabled with a valid HTTPS API address and ENCRYPTION_KEY; false: opt out.
# Partners still require mutual tenant approval under Zusammenarbeit.
FEDEO_FEDERATION_ENABLED=auto
GOCARDLESS_BASE_URL=https://api.gocardless.com
GOCARDLESS_SECRET_ID=replace-this
GOCARDLESS_SECRET_KEY=replace-this
DOKUBOX_IMAP_HOST=imap.example.com
DOKUBOX_IMAP_PORT=993
DOKUBOX_IMAP_SECURE=true
DOKUBOX_IMAP_USER=dokubox@example.com
DOKUBOX_IMAP_PASSWORD=change-this-imap-password
OPENAI_API_KEY=replace-this
STIRLING_API_KEY=replace-this
NUXT_PUBLIC_PDF_LICENSE=replace-with-your-pdf-license
# Interner Prometheus Node Exporter für die Admin-Systemstatusseite.
NODE_EXPORTER_URL=http://node-exporter:9100
# Lokaler Asterisk-Test für SIP/Voice. Aktivieren, wenn das Compose-Profil
# `telephony-dev` genutzt wird.
TELEPHONY_ENABLED=false
ASTERISK_IMAGE=andrius/asterisk:20
TELEPHONY_ASTERISK_HTTP_URL=http://asterisk-dev:8088/ws
TELEPHONY_ASTERISK_WS_URL=ws://localhost:8088/ws
TELEPHONY_ASTERISK_GENERATED_DIR=/var/lib/fedeo/asterisk/generated
TELEPHONY_ASTERISK_AMI_HOST=asterisk-dev
TELEPHONY_ASTERISK_AMI_PORT=5038
TELEPHONY_ASTERISK_AMI_USER=fedeo
TELEPHONY_ASTERISK_AMI_PASSWORD=fedeo-ami-dev
TELEPHONY_SIP_DOMAIN=localhost
TELEPHONY_TEST_EXTENSION=1001
TELEPHONY_TEST_PASSWORD=fedeo-test-1001
TELEPHONY_TEST_EXTENSION_2=1002
TELEPHONY_TEST_PASSWORD_2=fedeo-test-1002
TELEPHONY_ECHO_EXTENSION=600
TELEPHONY_DEV_WS_PORT=8088
TELEPHONY_DEV_AMI_PORT=5038
TELEPHONY_DEV_SIP_PORT=5060
TELEPHONY_DEV_RTP_MIN_PORT=10000
TELEPHONY_DEV_RTP_MAX_PORT=10100
TELEPHONY_ASTERISK_EXTERNAL_SIGNALING_ADDRESS=
TELEPHONY_ASTERISK_EXTERNAL_MEDIA_ADDRESS=
# Externe Telefonie über Telekom/tel.t-online.de. Keine echten Zugangsdaten
# einchecken. SIP-ID ist in der Regel die Rufnummer mit Vorwahl ohne Leerzeichen
# und ohne Sonderzeichen, z. B. 0301234567. Wenn dein Anschluss noch die
# Internet-Zugangsdaten als Auth-User nutzt, kann TELEPHONY_TELEKOM_AUTH_USER
# aus Anschlusskennung + Zugangsnummer + # + Mitbenutzernummer + @t-online.de
# gebildet werden.
TELEPHONY_EXTERNAL_PROVIDER=
TELEPHONY_EXTERNAL_ENABLED=false
TELEPHONY_EXTERNAL_INBOUND_EXTENSION=1001
TELEPHONY_TELEKOM_ENABLED=false
TELEPHONY_TELEKOM_REGISTRAR=tel.t-online.de
TELEPHONY_TELEKOM_SIP_USER=
TELEPHONY_TELEKOM_AUTH_USER=
TELEPHONY_TELEKOM_PASSWORD=
TELEPHONY_TELEKOM_CALLER_ID=
TELEPHONY_TELEKOM_INBOUND_EXTENSION=1001
TELEPHONY_TELEKOM_OUTBOUND_PREFIX=0
# Optionaler Erststart-Bootstrap. Wenn gesetzt, werden Admin, Mandant,
# Admin-Rolle und Grunddaten beim Backend-Start idempotent angelegt.
FEDEO_BOOTSTRAP_ADMIN_EMAIL=admin@example.com
FEDEO_BOOTSTRAP_ADMIN_PASSWORD=change-this-admin-password
FEDEO_BOOTSTRAP_ADMIN_FIRST_NAME=Admin
FEDEO_BOOTSTRAP_ADMIN_LAST_NAME=Benutzer
FEDEO_BOOTSTRAP_TENANT_NAME=Mein Unternehmen
FEDEO_BOOTSTRAP_TENANT_SHORT=MEIN

View File

@@ -0,0 +1,19 @@
---
name: 🐛 Bug Report
about: Erstelle einen Bericht, um uns zu helfen, das Projekt zu verbessern.
title: '[BUG] '
labels: Problem
assignees: ''
---
**Beschreibung**
**Reproduktion**
**Screenshots**
**Achtung: Achte bitte auf Datenschutz deiner Daten sowie der Daten deiner Kunden. Sollten ein Screenshot nur mit Daten möglich sein, schwärze diese bitte vor dem Upload.**

View File

@@ -0,0 +1,17 @@
---
name: ✨ Feature Request
about: Schlage eine Idee für dieses Projekt vor.
title: '[FEATURE] '
labels: Funktionswunsch
assignees: ''
---
**Ist dein Feature-Wunsch mit einem Problem verbunden?**
**Lösungsvorschlag**
**Alternativen**

View File

@@ -0,0 +1,57 @@
name: Build and Release FEDEO
on:
push:
branches: [dev, main]
workflow_dispatch:
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: '22'
- run: npm ci --ignore-scripts --no-audit --no-fund
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Test releases and selfhost updates
run: npm test
- name: Check Conventional Commits
run: npm run commits:check
build-and-release:
needs: verify
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
fetch-depth: 0
# dev uses the normal read-only checkout; only main needs a release writer.
token: ${{ github.ref == 'refs/heads/main' && (secrets.RELEASE_TOKEN || vars.RELEASE_TOKEN || vars.CI_TOKEN || secrets.CI_TOKEN) || github.token }}
- uses: actions/setup-node@v4
with:
node-version: '22'
- run: npm ci --ignore-scripts --no-audit --no-fund
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: git.federspiel.tech
username: flfeders
# Same credential source as the existing image-build workflows.
password: ${{ vars.CI_TOKEN || secrets.CI_TOKEN }}
- name: Build all images and publish main releases
# main uses a Git ref lock. dev only reads Git and writes to the registry.
env:
CI: 'true'
FEDEO_REF: ${{ github.ref }}
FEDEO_SHA: ${{ github.sha }}
FEDEO_EVENT_NAME: ${{ github.event_name }}
GITEA_TOKEN: ${{ github.ref == 'refs/heads/main' && (secrets.RELEASE_TOKEN || vars.RELEASE_TOKEN || vars.CI_TOKEN || secrets.CI_TOKEN) || '' }}
run: npm run release:ci

12
.gitignore vendored Normal file
View File

@@ -0,0 +1,12 @@
.env
node_modules/
.nuxt/
.output/
/.release/
__pycache__/
# Lokale Runtime-Daten und generierte Konfigurationen
matrix/postgres/
matrix/synapse/
matrix/dev/postgres/
matrix/dev/synapse/

8
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

12
.idea/FEDEO.iml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/FEDEO.iml" filepath="$PROJECT_DIR$/.idea/FEDEO.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

21
AGENTS.md Normal file
View File

@@ -0,0 +1,21 @@
# Projektanweisungen für FEDEO
## Git und Commit-Nachrichten
- Neue Projektdateien immer gezielt mit `git add` aufnehmen.
- Nach einem abgeschlossenen Arbeitsschritt die eigenen Änderungen committen. Bereits vorhandene Änderungen anderer Aufgaben nicht mitcommitten oder zurücksetzen.
- Jede selbst verfasste Commit-Nachricht muss Conventional Commits verwenden: `type(scope): Beschreibung`. Der Scope ist optional.
- `fix:` für Fehlerkorrekturen (Patch), `feat:` für neue Funktionen (Minor), `perf:` für Leistungsverbesserungen (Patch).
- `docs:`, `test:`, `refactor:`, `build:`, `ci:`, `chore:`, `style:` und `revert:` passend verwenden. Reine Wartungsänderungen lösen standardmäßig kein Release aus; Reverts können einen Patch auslösen.
- Inkompatible Änderungen mit `!` im Betreff und einem Footer `BREAKING CHANGE: Beschreibung und Migrationshinweis` markieren (Major). Diese Kennzeichnung niemals weglassen, um einen Versionssprung zu vermeiden.
- Beispiele: `fix(accounting): validate invoice totals`, `feat(stock): add inventory transfers`, `feat(api)!: replace legacy authentication`.
- Auch selbst verfasste Squash- und Merge-Betreffzeilen entsprechend benennen. Die Release-Auswertung liest die ursprünglichen Commits und überspringt echte Merge-Commits.
## Releases
- `dev` ist der Entwicklungszweig. Ein Push auf `main` ist der vom Benutzer gewählte Release-Auslöser; der Gitea-Workflow prüft, baut und veröffentlicht automatisch.
- Änderungen regulär auf dem aktuellen Entwicklungszweig committen. Erst bei einem ausdrücklichen Release-/Merge-/Push-Auftrag nach `main` übernehmen und pushen.
- Versionsnummern werden aus den Git-Tags `vMAJOR.MINOR.PATCH` und den Commit-Nachrichten berechnet. Keine manuellen Release-Commits oder Änderungen an Paketversionen für Backend/Frontend erzeugen.
- Vor Release-Arbeiten `docs/releases.md` lesen. Vorschau: `npm ci && npm run release:preview`. Prüfungen: `npm test && npm run commits:check`.
- Veröffentlichte Versions-Tags und Images niemals überschreiben oder löschen. Einen fehlgeschlagenen Release anhand der dokumentierten Wiederaufnahme fortsetzen.
- Mobile-App und Device-Agent behalten eigene Paketversionen; ihr Stand wird im Release-Manifest dokumentiert. App-Store-Veröffentlichungen haben einen eigenen Auslöser.

11
CHANGELOG.md Normal file
View File

@@ -0,0 +1,11 @@
# FEDEO Versionshistorie
Die Release-Pipeline erzeugt die Versionshistorie automatisch aus Conventional Commits.
- [Alle veröffentlichten Releases mit Änderungslisten](https://git.federspiel.tech/flfeders/FEDEO/releases)
- Jeder Release enthält seine Änderungen zusätzlich als herunterladbare `CHANGELOG.md`.
- `release-manifest.json` ordnet Version, Commit, Docker-Digests, Komponenten und Migrationen eindeutig zu.
Die Versionshistorie vor Einführung der Releases bleibt in der Git-Historie erhalten. Die automatische Reihe beginnt mit `v3.0.0`; Ausgangspunkt ist der in `release.config.json` dokumentierte Commit.
Die Pipeline schreibt keine automatischen Changelog-Commits zurück nach `main`. Dadurch bleiben Merge-Historie und Release-Auslöser eindeutig.

535
README.md
View File

@@ -1 +1,534 @@
TEST # FEDEO Hosting Guide
Diese Anleitung beschreibt ein produktionsnahes Self-Hosting von FEDEO mit Docker Compose, Traefik, PostgreSQL und optionalem S3-kompatiblem Objektspeicher via MinIO.
## Versionen und Releases
Ein Push auf `main` veröffentlicht nach erfolgreichen Prüfungen und Builds automatisch die nächste FEDEO-Version. Die Versionsnummer und Release Notes entstehen aus Conventional Commits (`fix:`, `feat:`, Breaking Changes). `dev` bleibt der Entwicklungskanal.
Für feste Selfhost-Versionen `FEDEO_VERSION` in `.env` auf eine veröffentlichte Version wie `3.0.0` setzen und die Betriebsdateien aus demselben Release verwenden. Ohne gesetzte Version bleibt der bisherige `dev`-Kanal aktiv. Die folgenden `raw/branch/dev`-Beispiele beschreiben diesen Entwicklungskanal.
Release-Freigabe, Einrichtung der CI-Tokens, versionierte Installation, Updates und Wiederaufnahme sind unter [Versionierung und Releases](docs/releases.md) beschrieben. Die laufende Backend-Version liefert `/backend/version`; im Frontend steht sie unten in der Seitenleiste.
## Architektur
Der Stack besteht aus:
- `frontend`: Nuxt-Frontend auf Port `3000`
- `backend`: Node/Fastify-API auf Port `3100`
- `db`: PostgreSQL
- `traefik`: Reverse Proxy mit automatischen Let's-Encrypt-Zertifikaten
- optional `minio`: S3-kompatibler Objektspeicher fur Dateiuploads
Die Konfiguration erfolgt uber Umgebungsvariablen beziehungsweise eine `.env`-Datei im Deploy-Verzeichnis.
## Voraussetzungen
Vor dem Deployment sollten folgende Punkte erfullt sein:
- Ein Linux-Server oder VPS mit offentlichen Ports `80` und `443`
- Docker Engine inkl. Compose Plugin
- Eine Domain, die auf den Server zeigt, z. B. `app.example.com`
- Optional: SMTP-Zugang fur E-Mails
- Optional: S3-Bucket oder MinIO fur Dateispeicher
Empfohlen:
- mindestens 2 vCPU
- mindestens 4 GB RAM
- SSD-Speicher fur PostgreSQL und Dateiuploads
## DNS und Netzwerk
Lege mindestens einen A- oder AAAA-Record an:
- `app.example.com -> <SERVER-IP>`
Traefik terminiert TLS direkt im Compose-Stack. Es ist kein zusatzlicher Reverse Proxy davor erforderlich.
## Benotigte Backend-Umgebungsvariablen
Das Backend erwartet mindestens diese Umgebungsvariablen:
- `COOKIE_SECRET`
- `JWT_SECRET`
- `PORT`
- `HOST`
- `DATABASE_URL`
- `S3_BUCKET`
- `ENCRYPTION_KEY`
- `MAILER_SMTP_HOST`
- `MAILER_SMTP_PORT`
- `MAILER_SMTP_SSL`
- `MAILER_SMTP_USER`
- `MAILER_SMTP_PASS`
- `MAILER_FROM`
- `S3_ENDPOINT`
- `S3_REGION`
- `S3_ACCESS_KEY`
- `S3_SECRET_KEY`
- `M2M_API_KEY`
- `API_BASE_URL`
- `GOCARDLESS_BASE_URL`
- `GOCARDLESS_SECRET_ID`
- `GOCARDLESS_SECRET_KEY`
- `DOKUBOX_IMAP_HOST`
- `DOKUBOX_IMAP_PORT`
- `DOKUBOX_IMAP_SECURE`
- `DOKUBOX_IMAP_USER`
- `DOKUBOX_IMAP_PASSWORD`
- `OPENAI_API_KEY`
- `STIRLING_API_KEY`
Minimal wichtige Werte fur den ersten Start:
- `HOST=0.0.0.0`
- `PORT=3100`
- `DATABASE_URL=postgres://fedeo:<starkes-passwort>@db:5432/fedeo`
- `API_BASE_URL=https://app.example.com/backend`
Die Chat-Föderation verwendet ebenfalls `API_BASE_URL`; Gastlinks übernehmen deren Ursprung. Mit gültiger öffentlicher HTTPS-Adresse auf Port 443 und vorhandenem gültigem `ENCRYPTION_KEY` ist sie automatisch verfügbar. Zusätzliche URLs sind nur bei abweichender Infrastruktur nötig (`FEDEO_FEDERATION_URL`, `FEDEO_PUBLIC_URL`). `FEDEO_FEDERATION_ENABLED=false` schaltet sie ausdrücklich ab; der Standard ist `auto`. Der Updater übernimmt die passenden Compose-Einträge aus dem Release. Partner müssen anschließend weiterhin je Mandant freigegeben werden; siehe [Föderation einrichten](docs/chat-foederation-konzept.md#15-implementierter-stand-und-pilotbetrieb).
Wenn du MinIO verwendest, setze zusatzlich:
- `S3_ENDPOINT=http://minio:9000`
- `S3_REGION=eu-central-1`
- `S3_ACCESS_KEY=<MINIO_ROOT_USER>`
- `S3_SECRET_KEY=<MINIO_ROOT_PASSWORD>`
- `S3_BUCKET=fedeo`
## Deploy-Struktur
Deploye den Stack in einem eigenen Betriebsverzeichnis. Der Selfhost-Installer lädt dafür nur die benötigten Betriebsdateien und klont nicht das komplette Repository.
Beispiel für die manuelle Vorbereitung:
```bash
mkdir -p /opt/fedeo/scripts
curl -fsSL https://git.federspiel.tech/flfeders/FEDEO/raw/branch/dev/docker-compose.selfhost.yml -o /opt/fedeo/docker-compose.yml
curl -fsSL https://git.federspiel.tech/flfeders/FEDEO/raw/branch/dev/.env.example -o /opt/fedeo/.env.example
curl -fsSL https://git.federspiel.tech/flfeders/FEDEO/raw/branch/dev/scripts/selfhost-setup.sh -o /opt/fedeo/scripts/selfhost-setup.sh
chmod +x /opt/fedeo/scripts/selfhost-setup.sh
```
Die Verzeichnisstruktur sollte dann mindestens so aussehen:
```text
/opt/fedeo/
docker-compose.yml
.env
scripts/
traefik/
letsencrypt/
logs/
postgres/
minio/
```
Danach:
```bash
mkdir -p /opt/fedeo/traefik/letsencrypt
mkdir -p /opt/fedeo/traefik/logs
mkdir -p /opt/fedeo/postgres
mkdir -p /opt/fedeo/minio
touch /opt/fedeo/traefik/letsencrypt/acme.json
chmod 600 /opt/fedeo/traefik/letsencrypt/acme.json
```
Als Startpunkt kannst du die Beispielumgebung kopieren:
```bash
cp .env.example .env
```
Ersetze anschließend alle Platzhalter und passe mindestens `DOMAIN`, `CONTACT_EMAIL`, Datenbank-, Secret-, SMTP- und S3-Werte an. Seafile ist kein Teil des Standard-Stacks; wenn FEDEO später Seafile als File-Backend nutzen soll, zeigst du die Seafile-Variablen auf einen externen Seafile-Dienst.
Alternativ kannst du die Konfiguration geführt erzeugen lassen:
```bash
bash scripts/selfhost-setup.sh
```
Auf einem frischen Server kannst du die Betriebsdateien und die Konfiguration direkt per One-Liner vorbereiten:
```bash
curl -fsSL https://git.federspiel.tech/flfeders/FEDEO/raw/branch/dev/scripts/selfhost-install.sh | bash
```
Der One-Liner von der Webseite nutzt den schnellen Standardpfad und startet den Stack direkt:
```bash
curl -fsSL https://git.federspiel.tech/flfeders/FEDEO/raw/branch/dev/scripts/selfhost-install.sh | bash -s -- --simple --start
```
Der Installer prüft Basispakete, installiert Docker auf Wunsch über das offizielle Docker-Installationsscript, lädt nur die Selfhost-Dateien nach `/opt/fedeo` und startet anschließend den geführten Setup-Assistenten.
Für den schnellen Standardpfad:
```bash
bash scripts/selfhost-setup.sh --simple
```
Für mehr Rückfragen zu SMTP, API-Schlüsseln und optionalen Diensten:
```bash
bash scripts/selfhost-setup.sh --advanced
```
Der Assistent erklärt zuerst die Selfhost-Verzeichnisstruktur, schreibt anschließend `.env`, legt persistente Verzeichnisse inklusive `traefik/letsencrypt/acme.json` an und kann den Stack optional direkt starten.
## Beispiel `.env`
Diese Datei liegt neben der `docker-compose.yml`:
```env
DOMAIN=app.example.com
CONTACT_EMAIL=admin@deine-domain.de
DB_NAME=fedeo
DB_USER=fedeo
DB_PASSWORD=change-this-db-password
DATABASE_URL=postgres://fedeo:change-this-db-password@db:5432/fedeo
MINIO_ROOT_USER=fedeo-minio
MINIO_ROOT_PASSWORD=change-this-minio-password
MINIO_BUCKET=fedeo
HOST=0.0.0.0
PORT=3100
COOKIE_SECRET=change-this-cookie-secret
JWT_SECRET=change-this-jwt-secret
ENCRYPTION_KEY=change-this-encryption-key
MAILER_SMTP_HOST=smtp.example.com
MAILER_SMTP_PORT=587
MAILER_SMTP_SSL=false
MAILER_SMTP_USER=mailer@example.com
MAILER_SMTP_PASS=change-this-mail-password
MAILER_FROM=FEDEO <no-reply@example.com>
S3_ENDPOINT=http://minio:9000
S3_REGION=eu-central-1
S3_ACCESS_KEY=fedeo-minio
S3_SECRET_KEY=change-this-minio-password
S3_BUCKET=fedeo
FEDEO_FILE_BACKEND=s3
SEAFILE_BASE_URL=https://files.example.com
SEAFILE_INTERNAL_URL=https://files.example.com
SEAFILE_ADMIN_EMAIL=admin@example.com
SEAFILE_ADMIN_PASSWORD=change-this-seafile-admin-password
M2M_API_KEY=change-this-m2m-key
API_BASE_URL=https://app.example.com/backend
GOCARDLESS_BASE_URL=https://api.gocardless.com
GOCARDLESS_SECRET_ID=replace-this
GOCARDLESS_SECRET_KEY=replace-this
DOKUBOX_IMAP_HOST=imap.example.com
DOKUBOX_IMAP_PORT=993
DOKUBOX_IMAP_SECURE=true
DOKUBOX_IMAP_USER=dokubox@example.com
DOKUBOX_IMAP_PASSWORD=change-this-imap-password
OPENAI_API_KEY=replace-this
STIRLING_API_KEY=replace-this
# Optional: zentrale, durch den FEDEO-Betreiber bereitgestellte Dienste
FEDEO_CENTRAL_SERVICES_ENABLED=false
PUSH_SERVER_URL=https://services.fedeo.de
PUSH_SERVER_INSTANCE_ID=
PUSH_SERVER_SECRET=
NUXT_PUBLIC_PDF_LICENSE=replace-with-your-pdf-license
FEDEO_BOOTSTRAP_ADMIN_EMAIL=admin@example.com
FEDEO_BOOTSTRAP_ADMIN_PASSWORD=change-this-admin-password
FEDEO_BOOTSTRAP_ADMIN_FIRST_NAME=Admin
FEDEO_BOOTSTRAP_ADMIN_LAST_NAME=Benutzer
FEDEO_BOOTSTRAP_TENANT_NAME=Mein Unternehmen
FEDEO_BOOTSTRAP_TENANT_SHORT=MEIN
```
Die `FEDEO_BOOTSTRAP_*`-Werte sind für den ersten Start gedacht. Wenn `FEDEO_BOOTSTRAP_ADMIN_EMAIL` und `FEDEO_BOOTSTRAP_ADMIN_PASSWORD` gesetzt sind, legt das Backend idempotent einen Admin-Benutzer, einen ersten Mandanten, eine Administrator-Rolle und grundlegende Stammdaten an. Nach erfolgreichem Erstzugriff solltest du das Bootstrap-Passwort aus der `.env` entfernen oder ändern.
## Docker Compose mit optionalem S3
Die Selfhost-Konfiguration wird im Betriebsverzeichnis als `docker-compose.yml` abgelegt. Sie startet MinIO standardmäßig mit. Wenn du stattdessen AWS S3, Hetzner Object Storage, Backblaze B2 S3 oder einen anderen externen S3-Dienst nutzen willst, kannst du die Services `minio` und `createbuckets` entfernen und nur die entsprechenden S3-Umgebungsvariablen auf den externen Anbieter zeigen lassen.
Seafile wird bewusst nicht im Standard-Compose-Stack gestartet. FEDEO kann später gegen einen extern betriebenen Seafile-Dienst sprechen; dafür bleiben `SEAFILE_BASE_URL`, `SEAFILE_INTERNAL_URL`, `SEAFILE_ADMIN_EMAIL` und `SEAFILE_ADMIN_PASSWORD` als generische Anbindungswerte vorgesehen. `FEDEO_FILE_BACKEND=s3` bleibt der Standard, bis die Backend-Integration für Seafile vollständig umgesetzt ist.
Das Backend führt beim Containerstart standardmäßig `npm run migrate` aus. Setze `FEDEO_RUN_MIGRATIONS=false`, wenn du Migrationen bewusst manuell ausführen möchtest.
```yaml
services:
traefik:
image: traefik:v2.11
container_name: fedeo-traefik
restart: unless-stopped
command:
- --api.insecure=false
- --api.dashboard=false
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --certificatesresolvers.letsencrypt.acme.tlschallenge=true
- --certificatesresolvers.letsencrypt.acme.email=${CONTACT_EMAIL}
- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
- --accesslog=true
- --accesslog.filepath=/logs/access.log
ports:
- "80:80"
- "443:443"
volumes:
- ./traefik/letsencrypt:/letsencrypt
- ./traefik/logs:/logs
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- web
db:
image: postgres:16
container_name: fedeo-db
restart: unless-stopped
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- ./postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
interval: 10s
timeout: 5s
retries: 10
networks:
- internal
minio:
image: minio/minio:latest
container_name: fedeo-minio
restart: unless-stopped
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
volumes:
- ./minio:/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 10s
timeout: 5s
retries: 10
networks:
- internal
createbuckets:
image: minio/mc:latest
container_name: fedeo-minio-init
depends_on:
minio:
condition: service_healthy
entrypoint: >
/bin/sh -c "
mc alias set local http://minio:9000 ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD};
mc mb --ignore-existing local/${MINIO_BUCKET};
mc anonymous set private local/${MINIO_BUCKET};
exit 0;
"
restart: "no"
networks:
- internal
backend:
image: git.federspiel.tech/flfeders/fedeo/backend:dev
container_name: fedeo-backend
restart: unless-stopped
depends_on:
db:
condition: service_healthy
minio:
condition: service_healthy
createbuckets:
condition: service_completed_successfully
environment:
NODE_ENV: production
HOST: ${HOST}
PORT: ${PORT}
COOKIE_SECRET: ${COOKIE_SECRET}
JWT_SECRET: ${JWT_SECRET}
ENCRYPTION_KEY: ${ENCRYPTION_KEY}
DATABASE_URL: ${DATABASE_URL}
MAILER_SMTP_HOST: ${MAILER_SMTP_HOST}
MAILER_SMTP_PORT: ${MAILER_SMTP_PORT}
MAILER_SMTP_SSL: ${MAILER_SMTP_SSL}
MAILER_SMTP_USER: ${MAILER_SMTP_USER}
MAILER_SMTP_PASS: ${MAILER_SMTP_PASS}
MAILER_FROM: ${MAILER_FROM}
S3_ENDPOINT: ${S3_ENDPOINT}
S3_REGION: ${S3_REGION}
S3_ACCESS_KEY: ${S3_ACCESS_KEY}
S3_SECRET_KEY: ${S3_SECRET_KEY}
S3_BUCKET: ${S3_BUCKET}
M2M_API_KEY: ${M2M_API_KEY}
API_BASE_URL: ${API_BASE_URL}
GOCARDLESS_BASE_URL: ${GOCARDLESS_BASE_URL}
GOCARDLESS_SECRET_ID: ${GOCARDLESS_SECRET_ID}
GOCARDLESS_SECRET_KEY: ${GOCARDLESS_SECRET_KEY}
DOKUBOX_IMAP_HOST: ${DOKUBOX_IMAP_HOST}
DOKUBOX_IMAP_PORT: ${DOKUBOX_IMAP_PORT}
DOKUBOX_IMAP_SECURE: ${DOKUBOX_IMAP_SECURE}
DOKUBOX_IMAP_USER: ${DOKUBOX_IMAP_USER}
DOKUBOX_IMAP_PASSWORD: ${DOKUBOX_IMAP_PASSWORD}
OPENAI_API_KEY: ${OPENAI_API_KEY}
STIRLING_API_KEY: ${STIRLING_API_KEY}
labels:
- traefik.enable=true
- traefik.http.routers.fedeo-backend.rule=Host(`${DOMAIN}`) && PathPrefix(`/backend`)
- traefik.http.routers.fedeo-backend.entrypoints=websecure
- traefik.http.routers.fedeo-backend.tls.certresolver=letsencrypt
- traefik.http.middlewares.fedeo-backend-strip.stripprefix.prefixes=/backend
- traefik.http.routers.fedeo-backend.middlewares=fedeo-backend-strip
- traefik.http.services.fedeo-backend.loadbalancer.server.port=3100
- traefik.docker.network=fedeo_web
networks:
- web
- internal
frontend:
image: git.federspiel.tech/flfeders/fedeo/frontend:dev
container_name: fedeo-frontend
restart: unless-stopped
depends_on:
- backend
environment:
NODE_ENV: production
NUXT_PUBLIC_API_BASE: https://${DOMAIN}/backend
NUXT_PUBLIC_PDF_LICENSE: ${NUXT_PUBLIC_PDF_LICENSE}
labels:
- traefik.enable=true
- traefik.http.routers.fedeo-frontend.rule=Host(`${DOMAIN}`)
- traefik.http.routers.fedeo-frontend.entrypoints=websecure
- traefik.http.routers.fedeo-frontend.tls.certresolver=letsencrypt
- traefik.http.services.fedeo-frontend.loadbalancer.server.port=3000
- traefik.docker.network=fedeo_web
networks:
- web
networks:
web:
name: fedeo_web
driver: bridge
internal:
name: fedeo_internal
driver: bridge
```
## Externe S3-Provider statt MinIO
Wenn du keinen lokalen MinIO-Container betreiben willst:
1. Entferne die Services `minio` und `createbuckets` aus der Compose-Datei.
2. Entferne im Backend `depends_on` fur `minio` und `createbuckets`.
3. Trage in `.env` die Zugangsdaten des externen S3-Dienstes ein.
Beispiel fur die relevanten Werte:
```env
S3_ENDPOINT=https://s3.eu-central-1.amazonaws.com
S3_REGION=eu-central-1
S3_ACCESS_KEY=...
S3_SECRET_KEY=...
S3_BUCKET=fedeo
```
Hinweis: Das Backend nutzt `forcePathStyle: true`. Das funktioniert sauber mit MinIO und vielen S3-kompatiblen Providern. Bei reinem AWS S3 kann je nach Endpoint-Setup ein abweichendes Verhalten sinnvoll sein. Falls du AWS S3 einsetzen willst, sollte die S3-Initialisierung im Backend gegen den konkreten Zielprovider getestet werden.
## Start des Stacks
Im Deploy-Verzeichnis:
```bash
docker compose --env-file /opt/fedeo/.env -f /opt/fedeo/docker-compose.yml up -d
```
Danach Status prufen:
```bash
docker compose --env-file /opt/fedeo/.env -f /opt/fedeo/docker-compose.yml ps
docker compose --env-file /opt/fedeo/.env -f /opt/fedeo/docker-compose.yml logs -f traefik
docker compose --env-file /opt/fedeo/.env -f /opt/fedeo/docker-compose.yml logs -f backend
```
Wenn du Migrationen manuell ausführen möchtest:
```bash
docker compose --env-file /opt/fedeo/.env -f /opt/fedeo/docker-compose.yml run --rm backend npm run migrate
```
## Funktionsprufung
Nach dem ersten Start sollten mindestens diese Checks erfolgreich sein:
```bash
curl -I https://app.example.com
curl https://app.example.com/backend/health
```
Erwartung:
- Frontend liefert `200` oder `302`
- Backend liefert JSON wie `{"status":"ok"}`
Wenn der Bootstrap aktiviert ist, kannst du dich danach mit `FEDEO_BOOTSTRAP_ADMIN_EMAIL` und `FEDEO_BOOTSTRAP_ADMIN_PASSWORD` anmelden. Die Mandantensperre wird über `locked` gesteuert; `hasActiveLicense` wird nicht mehr für den Selfhost-Zugriff ausgewertet.
## Updates
Vollständige Release-Updates einschließlich Compose-Datei werden mit dem Host-Skript vorbereitet und ausgeführt:
```bash
sudo python3 /opt/fedeo/scripts/selfhost-update.py check
sudo python3 /opt/fedeo/scripts/selfhost-update.py apply --version 3.1.0
sudo python3 /opt/fedeo/scripts/selfhost-update.py status
```
`3.1.0` durch den gewünschten veröffentlichten Release ersetzen. Das Skript benötigt Python ab 3.10 und Docker Compose ab 2.24. Es sichert die lokale Datenbank, MinIO, Konfiguration und Zertifikate vor dem Austausch, erhält `.env` und prüft die gestarteten Versionen. Während Backup und Aktualisierung gibt es eine Wartungsunterbrechung.
Beim ersten Update die erzeugte Compose-Differenz prüfen, eigene Anpassungen in eine Override-Datei übertragen und den Austausch mit `--accept-compose-replacement` bestätigen. Bestehende Installationen müssen das Update-Skript zunächst aus einem passenden Release übernehmen.
Unter **Administration → Systemstatus → FEDEO-Updates** können Systemadministratoren neue Releases prüfen und nach Bestätigung installieren. Dazu führt `fedeo-updater.service` die Aufträge unabhängig von Browser und Backend-Neustarts aus. Nach Bereitstellung der zugehörigen Dienstdateien installiert `sudo bash /opt/fedeo/scripts/selfhost-update-service-install.sh` den systemd-Dienst. Die aktuelle Selfhost-Compose-Datei bindet dessen lokales Socket-Verzeichnis im Backend ein. Bestehende Installationen benötigen einmalig die aktuellen Hostskripte und ein CLI-Update auf einen Release mit der Oberfläche. Einrichtung und Schritte stehen in der folgenden Anleitung.
Voraussetzungen, unterstützte Konfigurationen und Wiederherstellung stehen in [Vollständige Selfhost-Updates](docs/selfhost-updates.md). Für ältere Releases steht der manuelle Ablauf in [Versionierung und Releases](docs/releases.md).
## Backup-Empfehlung
Regelmassig sichern:
- PostgreSQL mit einem konsistenten Datenbankbackup, beispielsweise `pg_dump`
- `./minio` falls MinIO lokal genutzt wird
- `./traefik/letsencrypt/acme.json`
- deine `.env`
- deine dokumentierten Secret-Werte aus der `.env` oder deinem Secret-Management
## Bekannte Betriebsbesonderheiten
- Das Backend startet nur sauber, wenn alle Pflichtvariablen gesetzt sind.
- Ohne korrekt gesetzte S3-Secrets funktionieren Dateiuploads und dateibasierte Funktionen nicht.
- Fur die Frontend-PDF-Funktion wird eine gueltige `NUXT_PUBLIC_PDF_LICENSE` benotigt.
- PostgreSQL ist im Projekt vorgesehen; andere SQL-Datenbanken sind in dieser Compose-Datei nicht berucksichtigt.
## Optional: Nur mit bestehender externer Infrastruktur
Wenn bereits vorhanden:
- externer Reverse Proxy
- externer PostgreSQL-Server
- externer S3-Speicher
- externe Zertifikatsverwaltung
dann konnen `traefik`, `db` und `minio` aus dem Stack entfernt werden. In diesem Fall mussen die zugehorigen Hostnamen und Zugangsdaten in der `.env` beziehungsweise im Frontend-Environment auf die externe Infrastruktur zeigen.

View File

@@ -0,0 +1,8 @@
node_modules
dist
.venv-opencv
.env
*.log
*.tmp
__pycache__
tests

View File

@@ -0,0 +1,18 @@
FEDEO_URL=https://fedeo.example.com
FEDEO_AGENT_TOKEN=fedeo_agent_REPLACE_ME
FEDEO_POLL_SECONDS=5
FEDEO_WORK_DIR=/tmp/fedeo-device-agent
FEDEO_SCANNER_NAME=
FEDEO_PRINTER_NAME=
FEDEO_SCAN_FORMAT=pdf
FEDEO_SCAN_RESOLUTION=300
FEDEO_SCAN_MODE=Color
FEDEO_SCAN_SOURCE=
FEDEO_SCAN_TIMEOUT_SECONDS=900
FEDEO_SCAN_POSTPROCESS=false
FEDEO_SCAN_BACKGROUND_CLEANUP=true
FEDEO_SCAN_OCR=true
FEDEO_SCAN_OCR_LANGUAGE=deu+eng
FEDEO_SCAN_POSTPROCESS_PROFILE=document
FEDEO_SCAN_POSTPROCESS_PYTHON=
FEDEO_SCAN_POSTPROCESS_STRICT=false

7
agents/fedeo-device-agent/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
dist
node_modules
.venv-opencv
.env
*.log
*.tmp
__pycache__/

View File

@@ -0,0 +1,51 @@
FROM node:20-bookworm-slim AS build
WORKDIR /app
COPY package.json package-lock.json tsconfig.json ./
RUN npm ci
COPY src ./src
RUN npm run build
FROM node:20-bookworm-slim AS runtime
ENV NODE_ENV=production
ENV FEDEO_WORK_DIR=/work
ENV FEDEO_SCAN_POSTPROCESS=false
ENV FEDEO_SCAN_BACKGROUND_CLEANUP=true
ENV FEDEO_SCAN_OCR=true
ENV FEDEO_SCAN_OCR_LANGUAGE=deu+eng
ENV FEDEO_SCAN_POSTPROCESS_PROFILE=document
ENV FEDEO_SCAN_POSTPROCESS_PYTHON=/opt/fedeo-device-agent/.venv-opencv/bin/python
ENV FEDEO_SCAN_POSTPROCESS_STRICT=false
WORKDIR /opt/fedeo-device-agent
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
cups-client \
libgomp1 \
python3 \
python3-pip \
python3-venv \
sane-utils \
tesseract-ocr \
tesseract-ocr-deu \
tesseract-ocr-eng \
&& rm -rf /var/lib/apt/lists/*
COPY requirements-opencv.txt ./
RUN python3 -m venv .venv-opencv \
&& .venv-opencv/bin/python -m pip install --no-cache-dir --upgrade pip \
&& .venv-opencv/bin/python -m pip install --no-cache-dir -r requirements-opencv.txt \
&& .venv-opencv/bin/python -c "import cv2, PIL, numpy"
COPY --from=build /app/dist ./dist
COPY scripts ./scripts
COPY package.json ./
RUN mkdir -p /work
CMD ["node", "dist/main.js"]

View File

@@ -0,0 +1,250 @@
# FEDEO Geräte-Agent
Der FEDEO Geräte-Agent läuft lokal auf macOS, Linux oder Raspberry Pi OS. Er holt instanzweite Scan-Aufträge von FEDEO ab, führt sie auf einem lokal angeschlossenen Scanner aus und lädt das Ergebnis wieder in FEDEO hoch.
Der Agent ist nicht an einen Mandanten gebunden. Jeder Auftrag enthält seinen Tenant selbst.
## Geführte Linux-Installation in FEDEO
Unter **Administration → Scanner → Agent einrichten** führt ein Assistent durch die Einrichtung:
1. Rechner benennen und den Agenten anlegen.
2. Die vom Scanner-Rechner erreichbare FEDEO-Serveradresse prüfen. Ein Backend-Pfad wie `/backend` muss erhalten bleiben. Optional den Autostart bei der Linux-Anmeldung aktivieren.
3. **Linux-Installation herunterladen**. Die Datei enthält die Software und die persönliche Konfiguration; ein Projekt-Checkout oder `npm install` ist nicht nötig.
4. Auf dem Scanner-Rechner im Download-Ordner den angezeigten Befehl `bash fedeo-agent-<ID>.sh` ausführen, ohne vorangestelltes `sudo`. Fehlende Pakete werden auf Mint/Ubuntu/Debian über `sudo apt-get` installiert. Node.js muss mindestens Version 20 haben; bei einer älteren Distribution gegebenenfalls zuerst Node.js aktualisieren.
5. Der Assistent wartet auf eine aktuelle Meldung des Agenten. Danach den erkannten Scanner und beispielsweise das Profil **ScanSnap iX1600: A4, Duplex, PDF, 300 dpi** wählen und abschließen.
6. Optional **Testscan öffnen**. Der eingerichtete Agent ist vorausgewählt. Erst ein Klick auf **Scannen** startet den Einzug; das Ergebnis landet im Hauptordner des aktuellen Mandanten.
Die Installationsdatei enthält einen Zugangstoken. Nach erfolgreicher Einrichtung löschen oder geschützt aufbewahren. Unter **Einrichtung öffnen** lässt sich ein bestehender Agent erneut installieren. Dafür den gespeicherten Token einfügen oder ausdrücklich einen neuen erzeugen; der bisherige Zugang wird dabei sofort ungültig.
Die Installation ist je Agent getrennt:
- Software: `~/.local/share/fedeo-device-agent/<ID>/`
- Konfiguration mit Dateirechten `0600`: `~/.config/fedeo-device-agent/<ID>.env`
- Arbeitsdateien: `~/.local/state/fedeo-device-agent/<ID>/`
- Benutzerdienst: `fedeo-device-agent-<ID>.service`
Die entsprechenden XDG-Verzeichnisse werden berücksichtigt. Der Autostart beginnt bei der Benutzeranmeldung. Ohne Autostart muss das gestartete Terminal geöffnet bleiben. Protokolle: `journalctl --user -u fedeo-device-agent-<ID>.service -f`. Eine erneute Installation ersetzt nur die Dateien dieses Agenten.
### Scannerverwaltung meldet HTTP 500 nach einem Serverupdate
Die älteren Scanner-SQL-Dateien `0051` bis `0053` waren nicht im Drizzle-Migrationsjournal eingetragen und wurden dadurch bei regulären Updates übersprungen. Die Vorwärtsmigration `0072_restore_instance_scan_agents` legt fehlende Tabellen und Spalten nachträglich an. Vorhandene Agenten, Tokens, Einstellungen und Scanaufträge bleiben erhalten.
Zuerst einen Backend-Stand mit dieser Migration ausrollen. Bei aktiviertem `FEDEO_RUN_MIGRATIONS` wird sie beim Start automatisch ausgeführt. Bei bewusst deaktivierten Startmigrationen muss anschließend im aktualisierten Backend `npm run migrate` ausgeführt werden. Die alten Journal-Zeitstempel nachträglich einzufügen genügt bei bereits aktualisierten Datenbanken nicht.
Der Datenbanktest läuft isoliert gegen ein temporäres PostgreSQL-Image und verwendet keine Anwendungskonfiguration:
```bash
cd backend
FEDEO_TEST_POSTGRES_IMAGE=postgres:16-alpine node --import tsx tests/instanceAgentMigration.test.ts
```
## Voraussetzungen
### macOS
```bash
brew install node sane-backends tesseract tesseract-lang
scanimage -L
```
Für die Dateierstellung und Hintergrundbereinigung wird Python mit Pillow und OpenCV benötigt, beispielsweise über `npm run setup:opencv` (siehe unten). `tesseract --list-langs` muss für die Standardkonfiguration `deu` und `eng` enthalten.
Drucken nutzt später das macOS-Drucksystem/CUPS:
```bash
lpstat -p
```
### Linux und Raspberry Pi OS
```bash
sudo apt update
sudo apt install -y nodejs npm sane-utils python3-pil python3-opencv tesseract-ocr tesseract-ocr-deu tesseract-ocr-eng
scanimage -L
```
Node.js muss mindestens Version 20 haben (`node --version`). CUPS ist nur für die optionale Druckererkennung erforderlich.
## ScanSnap iX1600 unter Linux per USB
Der iX1600 wird vom SANE-Backend `fujitsu` per USB unterstützt. Die USB-ID ist `04c5:1632`; die WLAN-Schnittstelle wird von diesem Backend nicht unterstützt. Quellen: [SANE-Geräteliste](https://sane-project.gitlab.io/website/sane-mfgs.html), [Fujitsu-Backend](https://sane-project.gitlab.io/website/man/sane-fujitsu.5.html).
1. Scanner einschalten und per USB anschließen. `lsusb -d 04c5:1632` und `scanimage -L` müssen ihn anzeigen. Den vollständigen Gerätenamen übernehmen, beispielsweise `fujitsu:ScanSnap iX1600:123456`.
2. Den oben beschriebenen Einrichtungsassistenten verwenden. Für eine manuelle Installation kann alternativ die API `POST /api/instance-agents` als Administrator einen Agenten und dessen einmalig ausgegebenen Token erstellen.
3. Im Verzeichnis `agents/fedeo-device-agent` die Abhängigkeiten installieren und konfigurieren:
```bash
npm ci
cp .env.example .env
chmod 600 .env
nano .env
```
```env
FEDEO_URL=https://deine-fedeo-instanz
FEDEO_AGENT_TOKEN=fedeo_agent_DEIN_TOKEN
FEDEO_SCANNER_NAME="fujitsu:ScanSnap iX1600:DEINE_SERIENNUMMER"
FEDEO_SCAN_SOURCE="ADF Duplex"
FEDEO_SCAN_FORMAT=pdf
FEDEO_SCAN_RESOLUTION=300
FEDEO_SCAN_MODE=Color
FEDEO_SCAN_POSTPROCESS=false
FEDEO_SCAN_BACKGROUND_CLEANUP=true
FEDEO_SCAN_OCR=true
FEDEO_SCAN_OCR_LANGUAGE=deu+eng
FEDEO_SCAN_TIMEOUT_SECONDS=900
```
`FEDEO_URL` ist die Basis-URL, unter der `/instance-agent/heartbeat` erreichbar ist, ohne zusätzliches `/api`.
4. `npm run build` und `npm start` ausführen. In FEDEO muss der Agent als online erscheinen.
5. In der Scannerverwaltung das erkannte Gerät wählen, **ScanSnap iX1600: A4, Duplex, PDF** anklicken und speichern.
6. Papier einlegen. Unter **Dateien → Scan** den Agenten wählen und **Scannen** anklicken. Der gesamte Stapel landet als ein PDF im aktuellen Ordner. Für den ersten Test zwei Blätter mit markierten Vorder- und Rückseiten verwenden: Das PDF muss vier Seiten in dieser Reihenfolge enthalten.
Der Agent liest im SANE-Batch-Modus bis zum leeren Einzug. Vorder- und Rückseiten werden in der vom Scanner gelieferten Reihenfolge gespeichert, einschließlich leerer Rückseiten. Es gibt keine automatische Leerseitenentfernung. „ADF Front“ scannt einen Stapel einseitig, „Flatbed“ eine einzelne Seite. Einzug-Scans benötigen PDF; PNG und TIFF sind für Einzelseiten verfügbar. Die Optionen entsprechen dem [scanimage-Handbuch](https://sane-project.gitlab.io/website/man/scanimage.1.html).
**Papierformat:** Das iX1600-Profil verwendet A4 mit 210 × 297 mm, einschließlich der Fujitsu-Einstellungen für die Papiergröße. Für andere Größen die Einstellung anpassen; „Scanner-Vorgabe“ übernimmt den am Treiber eingestellten Scanbereich. Die SANE-Quellen und Optionen lassen sich ohne Scan mit `scanimage -d 'DEIN_GERAETENAME' --source 'ADF Duplex' --help` prüfen.
**USB-Zugriff:** Wenn `lsusb` das Gerät sieht, `scanimage -L` jedoch nicht, zuerst Kabel, Stromversorgung, SANE-Version und Zugriffsrechte prüfen. Debian/Ubuntu/Mint liefern normalerweise passende udev-Regeln mit `libsane-common`. Andere Scanprogramme schließen. Einen dauerhaft laufenden Agenten unter einem Benutzer betreiben, der ebenfalls mit `scanimage -L` auf das Gerät zugreifen kann.
**Lange Stapel und Fehler:** Das Scan-Zeitlimit beträgt standardmäßig 15 Minuten; die Dateierstellung hat ein eigenes gleich langes Limit. Der Agent hält seinen Online-Status währenddessen aktuell. Der Dialog kann im Hintergrund weiterlaufen; Schließen stoppt den Scan nicht. Verbindungsfehler beim Abfragen des Status lösen keinen neuen Scan aus. Bei Papierstau, unvollständigem Duplex-Scan oder Uploadfehler wird kein automatischer erneuter Papiereinzug gestartet. Die Rohseiten bzw. die fertige Datei bleiben im gemeldeten Arbeitsverzeichnis zur Wiederherstellung erhalten. Nach erfolgreichem Upload werden sie gelöscht. Das Upload-Limit beträgt 100 MiB pro PDF; gegebenenfalls den Stapel teilen oder die Auflösung reduzieren.
## Konfiguration
```bash
cp .env.example .env
nano .env
```
Wichtige Werte:
```env
FEDEO_URL=https://deine-fedeo-instanz
FEDEO_AGENT_TOKEN=fedeo_agent_...
FEDEO_SCANNER_NAME=
FEDEO_POLL_SECONDS=5
```
Wenn `FEDEO_SCANNER_NAME` leer bleibt, verwendet `scanimage` den Standard-Scanner.
## Entwicklung
```bash
npm ci
npm run dev
```
Nach Änderungen am Agenten oder am Linux-Installationsskript das im Frontend ausgelieferte Paket neu erstellen und mitcommitten:
```bash
npm run build:installer
```
`npm test` prüft mit `check:installer`, dass das Paket dem aktuellen Quellcode entspricht. Das Paket enthält keine Zugangsdaten; diese ergänzt erst der Browser beim Download. Die Installer-Tests verwenden temporäre Verzeichnisse und simulierte Systembefehle.
## Scannerhintergrund und OCR
Hintergrundbereinigung und OCR sind standardmäßig aktiv und lassen sich in **Administration → Scanner** als Vorgabe oder im einzelnen Scan-Dialog einstellen:
- **Scannerhintergrund weiß machen:** Bei einem kleinen Bon oder Dokument werden sicher erkannte Flächen außerhalb des Papiers weiß. Seitengröße, Position und Inhalt des Papiers bleiben erhalten. Unsichere Papiergrenzen werden nicht verändert. Diese Verarbeitung ist unabhängig vom zusätzlichen Zuschnitt.
- **Durchsuchbares PDF (OCR):** Der Agent erkennt nach der Bildverarbeitung Text mit Tesseract und bettet ihn direkt in das PDF ein, bevor er es hochlädt. Das gilt auch für normale Dateien ohne Eingangsbeleg. Deutsch und Englisch sind vorausgewählt; PNG und TIFF erhalten keine OCR-Textschicht. Die Darstellung bleibt das gescannte Bild, ergänzt um auswählbaren und durchsuchbaren Text ([Tesseract-Dokumentation](https://tesseract-ocr.github.io/tessdoc/Command-Line-Usage.html)).
```env
FEDEO_SCAN_BACKGROUND_CLEANUP=true
FEDEO_SCAN_OCR=true
FEDEO_SCAN_OCR_LANGUAGE=deu+eng
```
Nach einem Update von FEDEO bestehende Agenten über **Einrichtung öffnen** mit dem neuen Linux-Installer aktualisieren. Dieser installiert auch OpenCV, Tesseract und die Sprachpakete. Bei manueller Installation die oben genannten Pakete und die aktuelle Agent-Software installieren und den Dienst neu starten. Der Agent meldet die verfügbare Verarbeitung beim Start an FEDEO; fehlende Fähigkeiten werden vor dem Auftrag gemeldet. Zusätzlich prüft er die benötigten Pakete und die gewählte OCR-Sprache vor jedem Papiereinzug. Ein OCR-Fehler erzeugt keinen erfolgreichen Scan ohne Textschicht; die Rohseiten bleiben zur Wiederherstellung erhalten.
Die OCR läuft innerhalb des Scan-Auftrags nach dem Einzug. Bei langen Stapeln kann dieser Schritt länger dauern; das Zeitlimit für die Dateierstellung wird ebenfalls über `FEDEO_SCAN_TIMEOUT_SECONDS` gesetzt. Leere Rückseiten und Seitenreihenfolge bleiben erhalten.
## Zusätzliche OpenCV-Nachbearbeitung
Für automatischen Zuschnitt, leichte Entzerrung, Rotation und Kontrastkorrektur kann die OpenCV-Pipeline aktiviert werden.
```bash
npm run setup:opencv
```
Konfiguration:
```env
FEDEO_SCAN_POSTPROCESS=true
FEDEO_SCAN_POSTPROCESS_PROFILE=receipt
FEDEO_SCAN_POSTPROCESS_PYTHON=/pfad/zum/agent/.venv-opencv/bin/python
FEDEO_SCAN_POSTPROCESS_STRICT=false
```
Wenn `FEDEO_SCAN_POSTPROCESS_PYTHON` leer bleibt, verwendet der Agent automatisch `.venv-opencv/bin/python`, sofern diese Umgebung existiert, sonst `python3`. Pillow ist auch ohne Bildkorrektur für die Dateierstellung erforderlich. Falls die zusätzliche Korrektur fehlschlägt und `FEDEO_SCAN_POSTPROCESS_STRICT=false` gesetzt ist, werden die betroffenen Rohseiten weiterverarbeitet; die Warnung erscheint im Scan-Ergebnis. Fehlendes OpenCV kann nur bei ausgeschalteter Hintergrundbereinigung toleriert werden. Beim iX1600-Profil ist der zusätzliche Zuschnitt ausgeschaltet, damit der vollständige A4-Scan erhalten bleibt; Hintergrundbereinigung und OCR sind eingeschaltet.
Profile:
- `receipt`: Bons und schmale Belege werden bevorzugt hochkant zugeschnitten und kontrastiert.
- `document`: allgemeine Dokumente mit Farberhalt und moderater Verbesserung.
- `raw`: Zuschnitt/Entzerrung ohne starke Kontrastkorrektur.
## Container-Betrieb
Auf Linux und Raspberry Pi OS kann der Agent komplett im Container laufen. Dadurch bleiben Node.js, Python, OpenCV, Tesseract einschließlich Deutsch/Englisch und SANE im Image. Auf dem Host werden dann nur Docker und Zugriff auf den USB-Scanner benötigt.
```bash
cp .env.example .env
nano .env
docker compose -f docker-compose.example.yml up --build
```
Wenn FEDEO lokal auf dem Docker-Host läuft, verwende im Container nicht `localhost`, sondern:
```env
FEDEO_URL=http://host.docker.internal:3100
```
Scanner im Container prüfen:
```bash
docker compose -f docker-compose.example.yml run --rm fedeo-device-agent scanimage -L
```
Wenn der Scanner nicht sichtbar ist, hilft je nach Gerät/Host manchmal `privileged: true` im Compose-Beispiel. Auf macOS ist Docker dafür nur eingeschränkt geeignet, weil Docker Desktop USB-Scanner normalerweise nicht direkt an Linux-Container durchreichen kann. Für macOS bleibt deshalb der native Agent oder später eine signierte App der bessere Weg.
## Build
```bash
npm run build
npm start
```
## Tests
```bash
npm test
npm run test:python
```
Die Tests benötigen Python 3 mit Pillow, NumPy und OpenCV. Für den OCR-Integrationstest sind Tesseract mit `deu`/`eng` und `pdftotext` aus Poppler erforderlich; ohne diese Programme wird er übersprungen. Bei Verwendung der virtuellen Umgebung zuerst `. .venv-opencv/bin/activate` ausführen. Die Tests simulieren `scanimage`, erstellen echte PDFs und prüfen Duplex-/Simplex-Stapel, Seitenreihenfolge, Auflösung, leeren Einzug, Papierstau, beschädigte Seiten, Dateinamen und OpenCV-Ausfälle. Bildtests prüfen die Hintergrundbereinigung bei geraden und schrägen Bons sowie den Erhalt von Text, farbigen Logos und vollständigen Seiten. Der OCR-Test liest die tatsächliche PDF-Textschicht einschließlich leerer Rückseiten aus. Ein Test mit angeschlossenem iX1600 bleibt zusätzlich erforderlich.
Hardwareprüfung am 17.09.2026: ScanSnap iX1600 per USB unter Linux Mint 22.3 mit SANE 1.2.1. Zwei A4-Blätter wurden mit 300 dpi in Farbe beidseitig gescannt; das erzeugte PDF enthält vier A4-Seiten in der Reihenfolge Vorderseite/Rückseite. Alle vier Seiten wurden visuell geprüft. Der Test umfasste den lokalen Agenten bis zur PDF-Erstellung; der FEDEO-Upload wird separat mit einem simulierten Dateispeicher getestet.
## FEDEO-Endpunkte
Der Agent nutzt:
- `POST /instance-agent/heartbeat`
- `GET /instance-agent/scan-jobs/next`
- `POST /instance-agent/scan-jobs/:id/status`
- `POST /instance-agent/scan-jobs/:id/upload`
## macOS Autostart
Die Vorlage liegt unter `system/macos/com.fedeo.device-agent.plist`. Nach Anpassung der Pfade kann sie als LaunchAgent installiert werden:
```bash
mkdir -p ~/Library/LaunchAgents
cp system/macos/com.fedeo.device-agent.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.fedeo.device-agent.plist
```
## Linux Autostart
Die Vorlage liegt unter `system/linux/fedeo-device-agent.service`.

View File

@@ -0,0 +1,26 @@
services:
fedeo-device-agent:
build:
context: .
image: fedeo-device-agent:local
container_name: fedeo-device-agent
restart: unless-stopped
env_file:
- .env
environment:
FEDEO_WORK_DIR: /work
FEDEO_SCAN_POSTPROCESS_PYTHON: /opt/fedeo-device-agent/.venv-opencv/bin/python
FEDEO_SCAN_POSTPROCESS_STRICT: "false"
volumes:
- fedeo-device-agent-work:/work
# Optional fuer CUPS-Druck ueber den Host:
# - /var/run/cups/cups.sock:/var/run/cups/cups.sock
extra_hosts:
- "host.docker.internal:host-gateway"
devices:
- /dev/bus/usb:/dev/bus/usb
# Falls SANE den Scanner trotz devices-Mapping nicht sieht, testweise aktivieren:
# privileged: true
volumes:
fedeo-device-agent-work:

View File

@@ -0,0 +1,572 @@
{
"name": "@fedeo/device-agent",
"version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@fedeo/device-agent",
"version": "0.1.0",
"bin": {
"fedeo-device-agent": "dist/main.js"
},
"devDependencies": {
"@types/node": "^24.3.0",
"tsx": "^4.20.5",
"typescript": "^5.9.2"
},
"engines": {
"node": ">=20"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz",
"integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"aix"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz",
"integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz",
"integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz",
"integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz",
"integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz",
"integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz",
"integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz",
"integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz",
"integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz",
"integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz",
"integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz",
"integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz",
"integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz",
"integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz",
"integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz",
"integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz",
"integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz",
"integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz",
"integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz",
"integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz",
"integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openharmony-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz",
"integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz",
"integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz",
"integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz",
"integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz",
"integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@types/node": {
"version": "24.13.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.5.tgz",
"integrity": "sha512-TXyindR+lBr22aJIdMQzCFHPHR6cR4js838mRDCSz5hOKWZvZwsXSSiXDmjRj4iJmgl+sR9O+1mkoVBSMadNug==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~7.18.0"
}
},
"node_modules/esbuild": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz",
"integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.28.2",
"@esbuild/android-arm": "0.28.2",
"@esbuild/android-arm64": "0.28.2",
"@esbuild/android-x64": "0.28.2",
"@esbuild/darwin-arm64": "0.28.2",
"@esbuild/darwin-x64": "0.28.2",
"@esbuild/freebsd-arm64": "0.28.2",
"@esbuild/freebsd-x64": "0.28.2",
"@esbuild/linux-arm": "0.28.2",
"@esbuild/linux-arm64": "0.28.2",
"@esbuild/linux-ia32": "0.28.2",
"@esbuild/linux-loong64": "0.28.2",
"@esbuild/linux-mips64el": "0.28.2",
"@esbuild/linux-ppc64": "0.28.2",
"@esbuild/linux-riscv64": "0.28.2",
"@esbuild/linux-s390x": "0.28.2",
"@esbuild/linux-x64": "0.28.2",
"@esbuild/netbsd-arm64": "0.28.2",
"@esbuild/netbsd-x64": "0.28.2",
"@esbuild/openbsd-arm64": "0.28.2",
"@esbuild/openbsd-x64": "0.28.2",
"@esbuild/openharmony-arm64": "0.28.2",
"@esbuild/sunos-x64": "0.28.2",
"@esbuild/win32-arm64": "0.28.2",
"@esbuild/win32-ia32": "0.28.2",
"@esbuild/win32-x64": "0.28.2"
}
},
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/tsx": {
"version": "4.23.13",
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.13.tgz",
"integrity": "sha512-BL5MGkRln6aDYhb0xbQlEAGw743BaZYWdbWtdJOBriYJboKgUUYCadFp2/FpBBZquBC/ezNBn7wMMPx7FDZUDw==",
"dev": true,
"license": "MIT",
"dependencies": {
"esbuild": "~0.28.0"
},
"bin": {
"tsx": "dist/cli.mjs"
},
"engines": {
"node": ">=18.0.0"
},
"optionalDependencies": {
"fsevents": "~2.3.3"
}
},
"node_modules/typescript": {
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "7.18.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
"integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
"dev": true,
"license": "MIT"
}
}
}

View File

@@ -0,0 +1,30 @@
{
"name": "@fedeo/device-agent",
"version": "0.1.0",
"private": true,
"description": "Lokaler FEDEO Druck- und Scan-Agent für macOS, Linux und Raspberry Pi OS.",
"type": "module",
"main": "dist/main.js",
"bin": {
"fedeo-device-agent": "dist/main.js"
},
"scripts": {
"build": "tsc -p tsconfig.json",
"build:installer": "npm run build && node scripts/build-installer.mjs",
"check:installer": "npm run build && node scripts/build-installer.mjs --check",
"dev": "tsx src/main.ts",
"start": "node dist/main.js",
"test": "node --import tsx --test tests/*.test.ts && node --test tests/*.test.mjs && npm run check:installer",
"test:python": "python3 -m unittest discover -s tests -p '*_test.py'",
"setup:opencv": "sh scripts/setup-opencv.sh"
},
"dependencies": {},
"devDependencies": {
"@types/node": "^24.3.0",
"tsx": "^4.20.5",
"typescript": "^5.9.2"
},
"engines": {
"node": ">=20"
}
}

View File

@@ -0,0 +1,3 @@
opencv-python-headless>=4.9
Pillow>=10.0
numpy>=1.26

View File

@@ -0,0 +1,40 @@
import { readFile, readdir, mkdir, writeFile } from 'node:fs/promises'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
const output = path.resolve(root, '../../frontend/assets/device-agent/bundle.json')
async function filesUnder(directory) {
const entries = await readdir(path.join(root, directory), { withFileTypes: true })
const paths = await Promise.all(entries.map(entry => entry.isDirectory()
? filesUnder(`${directory}/${entry.name}`)
: [`${directory}/${entry.name}`]))
return paths.flat().sort()
}
const packageJson = JSON.parse(await readFile(path.join(root, 'package.json'), 'utf8'))
const paths = [
...(await filesUnder('dist')).filter(file => file.endsWith('.js')),
'scripts/scan_document.py', 'scripts/scan_background.py', 'scripts/opencv_postprocess.py', 'scripts/setup-opencv.sh',
'requirements-opencv.txt',
]
const files = Object.fromEntries(await Promise.all(paths.map(async file => [file, (await readFile(path.join(root, file))).toString('base64')])))
files['package.json'] = Buffer.from(JSON.stringify({
name: packageJson.name, version: packageJson.version, type: 'module', engines: packageJson.engines,
scripts: { start: 'node dist/main.js', 'setup:opencv': 'sh scripts/setup-opencv.sh' },
}, null, 2) + '\n').toString('base64')
const bundle = JSON.stringify({
version: packageJson.version,
installerTemplate: await readFile(path.join(root, 'scripts/install-linux.sh'), 'utf8'),
files,
}, null, 2) + '\n'
if (process.argv.includes('--check')) {
if (await readFile(output, 'utf8') !== bundle) {
throw new Error('Das Installationspaket ist veraltet. Bitte npm run build:installer ausführen und bundle.json mitcommitten.')
}
console.log('Installationspaket entspricht dem aktuellen Agenten.')
} else {
await mkdir(path.dirname(output), { recursive: true })
await writeFile(output, bundle)
console.log(`Installationspaket erstellt: ${output}`)
}

View File

@@ -0,0 +1,118 @@
#!/usr/bin/env bash
# Generated by the FEDEO setup wizard. This file contains the agent's access token.
set -euo pipefail
umask 077
if [[ "$(uname -s)" != Linux ]]; then
echo 'Diese Installation ist für Linux vorgesehen.' >&2
exit 1
fi
if [[ "$(id -u)" == 0 ]]; then
echo 'Bitte dieses Skript als normaler Benutzer ohne sudo starten.' >&2
exit 1
fi
if [[ "${1:-}" != '' && "${1:-}" != --no-start ]]; then
echo 'Aufruf: bash install.sh [--no-start]' >&2
exit 1
fi
FEDEO_SETUP_ID='@@AGENT_ID@@'
FEDEO_SETUP_AUTOSTART='@@AUTOSTART@@'
FEDEO_SETUP_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/fedeo-device-agent/$FEDEO_SETUP_ID"
FEDEO_SETUP_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/fedeo-device-agent/$FEDEO_SETUP_ID.env"
FEDEO_SETUP_WORK="${XDG_STATE_HOME:-$HOME/.local/state}/fedeo-device-agent/$FEDEO_SETUP_ID"
FEDEO_SETUP_UNIT="fedeo-device-agent-$FEDEO_SETUP_ID.service"
FEDEO_SETUP_UNITS="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user"
echo 'FEDEO Scan-Agent wird für diesen Benutzer eingerichtet.'
fedeo_processing_ready() {
python3 -c 'import PIL, cv2, numpy' >/dev/null 2>&1 &&
tesseract --list-langs 2>/dev/null | grep -qx deu &&
tesseract --list-langs 2>/dev/null | grep -qx eng
}
if ! command -v node >/dev/null || ! command -v scanimage >/dev/null || ! fedeo_processing_ready; then
if ! command -v apt-get >/dev/null; then
echo 'Bitte Node.js >= 20, SANE, Python/Pillow/OpenCV sowie Tesseract mit Deutsch/Englisch installieren und das Skript erneut starten.' >&2
exit 1
fi
echo 'Fehlende Systempakete werden über apt installiert (sudo benötigt).'
sudo apt-get update
sudo apt-get install -y nodejs sane-utils python3-pil python3-opencv tesseract-ocr tesseract-ocr-deu tesseract-ocr-eng
fi
node -e 'if (Number(process.versions.node.split(".")[0]) < 20) { console.error("Node.js >= 20 wird benötigt. Bitte Node.js aktualisieren und die Installation erneut starten."); process.exit(1) }'
fedeo_processing_ready || { echo 'Die benötigte Bildverarbeitung oder die OCR-Sprachpakete fehlen weiterhin.' >&2; exit 1; }
FEDEO_SETUP_NODE="$(command -v node)"
FEDEO_SETUP_HAS_SYSTEMD=false
if command -v systemctl >/dev/null && systemctl --user show-environment >/dev/null 2>&1; then
FEDEO_SETUP_HAS_SYSTEMD=true
fi
if [[ "$FEDEO_SETUP_AUTOSTART" == true && "$FEDEO_SETUP_HAS_SYSTEMD" != true ]]; then
echo 'Der Benutzerdienst von systemd ist nicht erreichbar. Bitte in der Desktop-Sitzung starten oder den Autostart im Assistenten ausschalten.' >&2
exit 1
fi
mkdir -p "$FEDEO_SETUP_DIR" "$(dirname "$FEDEO_SETUP_CONFIG")" "$FEDEO_SETUP_WORK" "$FEDEO_SETUP_UNITS"
# Stop only the matching installation before replacing its files.
if [[ "$FEDEO_SETUP_HAS_SYSTEMD" == true && "${1:-}" != --no-start ]]; then
systemctl --user stop "$FEDEO_SETUP_UNIT" 2>/dev/null || true
fi
python3 - "$FEDEO_SETUP_DIR" "$FEDEO_SETUP_CONFIG" "$FEDEO_SETUP_WORK" "$FEDEO_SETUP_NODE" "$FEDEO_SETUP_UNITS/$FEDEO_SETUP_UNIT" <<'FEDEO_PYTHON'
import base64
import json
import os
from pathlib import Path
import sys
agent_dir, config_path, work_dir, node, unit_path = map(Path, sys.argv[1:])
files = json.loads(base64.b64decode('@@PAYLOAD_BASE64@@'))
for name, encoded in files.items():
relative = Path(name)
if relative.is_absolute() or '..' in relative.parts:
raise ValueError('Ungültiger Dateiname im Installationspaket')
target = agent_dir / relative
target.parent.mkdir(parents=True, exist_ok=True)
target.write_bytes(base64.b64decode(encoded, validate=True))
config = base64.b64decode('@@CONFIG_BASE64@@').decode('utf8')
config += 'FEDEO_WORK_DIR=' + str(work_dir) + '\n'
config_path.write_text(config, encoding='utf8')
config_path.chmod(0o600)
def unit_quote(value):
return '"' + str(value).replace('\\', '\\\\').replace('"', '\\"').replace('%', '%%') + '"'
unit_path.write_text('\n'.join([
'[Unit]', 'Description=FEDEO Scan-Agent', 'After=network-online.target', '',
'[Service]', 'Type=simple',
# WorkingDirectory takes a literal path, unlike Environment/ExecStart.
# Quotes would become part of the path; only systemd specifiers need escaping.
'WorkingDirectory=' + str(agent_dir).replace('%', '%%'),
'Environment=' + unit_quote('FEDEO_AGENT_ENV=' + str(config_path)),
'ExecStart=' + unit_quote(node) + ' ' + unit_quote(agent_dir / 'dist/main.js'),
'Restart=on-failure', 'RestartSec=5', 'UMask=0077', '',
'[Install]', 'WantedBy=default.target', '',
]), encoding='utf8')
FEDEO_PYTHON
echo "Agent installiert: $FEDEO_SETUP_DIR"
echo "Konfiguration: $FEDEO_SETUP_CONFIG"
if [[ "${1:-}" == --no-start ]]; then
echo 'Installation abgeschlossen; Agent wurde nicht gestartet.'
elif [[ "$FEDEO_SETUP_AUTOSTART" == true ]]; then
systemctl --user daemon-reload
systemctl --user enable "$FEDEO_SETUP_UNIT"
systemctl --user restart "$FEDEO_SETUP_UNIT"
echo 'Agent gestartet. Er startet künftig bei der Anmeldung.'
printf 'Protokoll: journalctl --user -u %q -f\n' "$FEDEO_SETUP_UNIT"
echo 'Jetzt im FEDEO-Assistenten die Verbindung prüfen. Die heruntergeladene Installationsdatei kann anschließend gelöscht werden.'
else
if [[ "$FEDEO_SETUP_HAS_SYSTEMD" == true ]]; then
systemctl --user disable "$FEDEO_SETUP_UNIT" 2>/dev/null || true
systemctl --user daemon-reload
fi
echo 'Agent startet im Terminal. Dieses Fenster geöffnet lassen; Beenden mit Strg+C.'
cd "$FEDEO_SETUP_DIR"
FEDEO_AGENT_ENV="$FEDEO_SETUP_CONFIG" "$FEDEO_SETUP_NODE" dist/main.js
fi

View File

@@ -0,0 +1,219 @@
#!/usr/bin/env python3
import argparse
import math
from pathlib import Path
import cv2
import numpy as np
from PIL import Image
def order_points(points):
rect = np.zeros((4, 2), dtype="float32")
point_sum = points.sum(axis=1)
point_diff = np.diff(points, axis=1)
rect[0] = points[np.argmin(point_sum)]
rect[2] = points[np.argmax(point_sum)]
rect[1] = points[np.argmin(point_diff)]
rect[3] = points[np.argmax(point_diff)]
return rect
def four_point_transform(image, points):
rect = order_points(points)
top_left, top_right, bottom_right, bottom_left = rect
width_a = np.linalg.norm(bottom_right - bottom_left)
width_b = np.linalg.norm(top_right - top_left)
max_width = int(max(width_a, width_b))
height_a = np.linalg.norm(top_right - bottom_right)
height_b = np.linalg.norm(top_left - bottom_left)
max_height = int(max(height_a, height_b))
destination = np.array([
[0, 0],
[max_width - 1, 0],
[max_width - 1, max_height - 1],
[0, max_height - 1],
], dtype="float32")
matrix = cv2.getPerspectiveTransform(rect, destination)
return cv2.warpPerspective(image, matrix, (max_width, max_height), borderValue=(255, 255, 255))
def rotate_bound(image, angle):
height, width = image.shape[:2]
center = (width / 2, height / 2)
matrix = cv2.getRotationMatrix2D(center, angle, 1.0)
cos = abs(matrix[0, 0])
sin = abs(matrix[0, 1])
new_width = int((height * sin) + (width * cos))
new_height = int((height * cos) + (width * sin))
matrix[0, 2] += (new_width / 2) - center[0]
matrix[1, 2] += (new_height / 2) - center[1]
return cv2.warpAffine(image, matrix, (new_width, new_height), borderValue=(255, 255, 255))
def deskew_by_text_angle(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
inverted = cv2.bitwise_not(gray)
threshold = cv2.threshold(inverted, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
coordinates = np.column_stack(np.where(threshold > 0))
if len(coordinates) < 500:
return image
angle = cv2.minAreaRect(coordinates)[-1]
if angle < -45:
angle = -(90 + angle)
else:
angle = -angle
if abs(angle) < 0.2 or abs(angle) > 8:
return image
return rotate_bound(image, angle)
def find_document_contour(image, profile):
ratio = image.shape[0] / 900.0
resized = cv2.resize(image, (int(image.shape[1] / ratio), 900))
gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edges = cv2.Canny(gray, 45, 140)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
edges = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=cv2.contourArea, reverse=True)[:8]
min_area = resized.shape[0] * resized.shape[1] * (0.03 if profile == "receipt" else 0.12)
for contour in contours:
if cv2.contourArea(contour) < min_area:
continue
perimeter = cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, 0.025 * perimeter, True)
if len(approx) == 4:
return approx.reshape(4, 2) * ratio
return None
def trim_light_border(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
mask = cv2.threshold(gray, 245, 255, cv2.THRESH_BINARY_INV)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 9))
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if not contours:
return image
contour = max(contours, key=cv2.contourArea)
if cv2.contourArea(contour) < image.shape[0] * image.shape[1] * 0.02:
return image
x, y, width, height = cv2.boundingRect(contour)
padding = max(12, int(min(width, height) * 0.025))
x = max(0, x - padding)
y = max(0, y - padding)
width = min(image.shape[1] - x, width + padding * 2)
height = min(image.shape[0] - y, height + padding * 2)
return image[y:y + height, x:x + width]
def enhance_receipt(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
gray = clahe.apply(gray)
gray = cv2.fastNlMeansDenoising(gray, None, 8, 7, 21)
gray = cv2.normalize(gray, None, 0, 255, cv2.NORM_MINMAX)
return cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
def enhance_document(image):
lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
l_channel, a_channel, b_channel = cv2.split(lab)
clahe = cv2.createCLAHE(clipLimit=1.6, tileGridSize=(8, 8))
l_channel = clahe.apply(l_channel)
return cv2.cvtColor(cv2.merge((l_channel, a_channel, b_channel)), cv2.COLOR_LAB2BGR)
def auto_rotate_profile(image, profile):
height, width = image.shape[:2]
if profile == "receipt" and width > height:
return cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)
return image
def postprocess(input_path, output_path, profile):
image = cv2.imread(str(input_path), cv2.IMREAD_COLOR)
if image is None:
raise RuntimeError(f"OpenCV konnte {input_path} nicht lesen")
contour = find_document_contour(image, profile)
if contour is not None:
processed = four_point_transform(image, contour.astype("float32"))
else:
processed = trim_light_border(image)
processed = deskew_by_text_angle(processed)
processed = trim_light_border(processed)
processed = auto_rotate_profile(processed, profile)
if profile == "receipt":
processed = enhance_receipt(processed)
elif profile != "raw":
processed = enhance_document(processed)
save_output(processed, output_path)
def save_output(image, output_path):
suffix = output_path.suffix.lower()
if suffix == ".pdf":
rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
pil_image = Image.fromarray(rgb)
if pil_image.mode != "RGB":
pil_image = pil_image.convert("RGB")
pil_image.save(output_path, "PDF", resolution=300.0)
return
if suffix in {".jpg", ".jpeg"}:
cv2.imwrite(str(output_path), image, [cv2.IMWRITE_JPEG_QUALITY, 92])
return
if suffix == ".png":
cv2.imwrite(str(output_path), image, [cv2.IMWRITE_PNG_COMPRESSION, 3])
return
if suffix in {".tif", ".tiff"}:
cv2.imwrite(str(output_path), image)
return
raise RuntimeError(f"Nicht unterstütztes Ausgabeformat: {suffix}")
def main():
parser = argparse.ArgumentParser(description="FEDEO Scan-Nachbearbeitung mit OpenCV")
parser.add_argument("--input", required=True)
parser.add_argument("--output", required=True)
parser.add_argument("--profile", default="document", choices=["document", "receipt", "raw"])
args = parser.parse_args()
postprocess(Path(args.input), Path(args.output), args.profile)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,74 @@
"""Conservative paper masking. Keep the canvas and every pixel inside the paper."""
from pathlib import Path
import cv2
import numpy as np
def whiten_background(image):
height, width = image.shape[:2]
scale = min(1.0, 1000.0 / max(height, width))
small = cv2.resize(image, None, fx=scale, fy=scale, interpolation=cv2.INTER_AREA)
gray = cv2.cvtColor(small, cv2.COLOR_BGR2GRAY)
border = np.concatenate((gray[0], gray[-1], gray[:, 0], gray[:, -1]))
background = float(np.median(border))
# White surroundings already need no correction. Never search inside a
# white document for an isolated text box or logo to keep instead.
if background >= 235 or np.percentile(border, 75) - np.percentile(border, 25) > 55:
return image
threshold, _ = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
mask = np.uint8(gray > max(threshold, background + 20)) * 255
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, np.ones((5, 5), np.uint8))
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
candidates = []
area = gray.size
for contour in contours:
contour_area = cv2.contourArea(contour)
if not 0.015 * area < contour_area < 0.985 * area:
continue
perimeter = cv2.arcLength(contour, True)
polygon = cv2.approxPolyDP(contour, 0.018 * perimeter, True)
if len(polygon) != 4 or not cv2.isContourConvex(polygon):
continue
# Use the quadrilateral only to recognize a sheet, then keep its full
# contour hull so rounded or slightly uneven edges cannot lose content.
polygon = cv2.convexHull(contour)
paper = np.zeros_like(gray)
cv2.fillPoly(paper, [polygon], 255)
inside = cv2.erode(paper, np.ones((7, 7), np.uint8)) > 0
ring = (cv2.dilate(paper, np.ones((9, 9), np.uint8)) > 0) & (paper == 0)
if inside.sum() < 100 or ring.sum() < 50:
continue
paper_light = float(np.median(gray[inside]))
# A paper edge must separate a mostly light sheet from darker scanner
# backing all around it. Ambiguous photos/pages are left untouched.
if paper_light < background + 30 or np.mean(gray[ring] < paper_light - 20) < 0.85:
continue
candidates.append(polygon)
if not candidates:
return image
keep_small = np.zeros_like(gray)
cv2.fillPoly(keep_small, candidates, 255)
# Do not erase another significant object that we could not classify.
outside = (keep_small == 0)
if np.mean(gray[outside] > background + 30) > 0.04:
return image
keep = np.zeros((height, width), dtype=np.uint8)
polygons = [np.rint(polygon / scale).astype(np.int32) for polygon in candidates]
cv2.fillPoly(keep, polygons, 255)
# Rounding/downsampling uncertainty grows with the original scan DPI.
padding = max(2, int(np.ceil(2 / scale)))
keep = cv2.dilate(keep, np.ones((2 * padding + 1, 2 * padding + 1), np.uint8))
result = image.copy()
result[keep == 0] = 255
return result
def clean_scan_background(input_path: Path, output_path: Path):
image = cv2.imread(str(input_path), cv2.IMREAD_COLOR)
if image is None:
raise RuntimeError("Scan-Bild konnte nicht gelesen werden")
if not cv2.imwrite(str(output_path), whiten_background(image)):
raise RuntimeError("Bereinigtes Scan-Bild konnte nicht gespeichert werden")

View File

@@ -0,0 +1,154 @@
#!/usr/bin/env python3
"""Prepare ordered scanner pages and publish an optionally searchable PDF atomically."""
import argparse
import json
import math
from pathlib import Path
import re
import signal
import subprocess
import tempfile
from PIL import Image, PdfParser
def run_ocr_command(arguments):
process = subprocess.Popen(arguments, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
try:
stdout, stderr = process.communicate()
except BaseException:
process.kill()
process.wait()
raise
if process.returncode != 0:
raise RuntimeError("OCR fehlgeschlagen: " + stderr.strip())
return stdout
def check_ocr(language):
if not re.fullmatch(r"[a-zA-Z0-9_]+(?:\+[a-zA-Z0-9_]+)*", language):
raise ValueError("Ungültige OCR-Sprache")
try:
languages = run_ocr_command(["tesseract", "--list-langs"]).splitlines()
except FileNotFoundError as error:
raise RuntimeError("Tesseract fehlt. Bitte tesseract-ocr und die Sprachpakete tesseract-ocr-deu/tesseract-ocr-eng installieren.") from error
missing = set(language.split("+")) - {line.strip() for line in languages}
if missing:
raise RuntimeError("OCR-Sprachpakete fehlen: " + ", ".join(sorted(missing)))
def create_document(inputs, output, resolution, use_postprocess=False, profile="document", strict=False,
ocr=False, ocr_language="deu+eng", background_cleanup=False):
if not inputs:
raise ValueError("Keine Seiten vorhanden")
if not math.isfinite(resolution) or resolution <= 0:
raise ValueError("Ungültige Scan-Auflösung")
output = Path(output)
file_format = {".pdf": "PDF", ".png": "PNG", ".tiff": "TIFF"}.get(output.suffix.lower())
if not file_format:
raise ValueError("Unbekanntes Ausgabeformat")
if (len(inputs) != 1 or ocr) and file_format != "PDF":
raise ValueError("Mehrseitige Scans und OCR benötigen PDF als Ausgabeformat")
if ocr:
check_ocr(ocr_language)
warnings = []
processor = None
if use_postprocess:
try:
from opencv_postprocess import postprocess
processor = postprocess
except ImportError:
if strict:
raise
warnings.append("OpenCV fehlt; alle Seiten wurden ohne Bildkorrektur übernommen.")
if background_cleanup:
from scan_background import clean_scan_background
partial = output.with_name(output.name + ".partial")
try:
with tempfile.TemporaryDirectory(prefix="prepared-", dir=output.parent) as directory:
prepared = []
for index, input_path in enumerate(inputs):
image_path = Path(input_path)
corrected = Path(directory) / f"corrected-{index:06}.png"
if processor:
try:
processor(image_path, corrected, profile)
image_path = corrected
except Exception:
if strict:
raise
warnings.append(f"Seite {index + 1}: Bildkorrektur fehlgeschlagen; Rohscan übernommen.")
if background_cleanup:
cleaned = Path(directory) / f"cleaned-{index:06}.png"
clean_scan_background(image_path, cleaned)
image_path = cleaned
# Only one decoded page is kept in memory, even for duplex stacks.
with Image.open(image_path) as image:
with image.convert("RGB") as rgb:
if ocr:
page = Path(directory).resolve() / f"page-{index:06}.png"
rgb.save(page, "PNG", dpi=(resolution, resolution))
prepared.append(page)
elif file_format == "PDF":
rgb.save(partial, "PDF", resolution=resolution, quality=90, append=index > 0)
else:
rgb.save(partial, file_format, dpi=(resolution, resolution))
corrected.unlink(missing_ok=True)
if background_cleanup:
cleaned.unlink(missing_ok=True)
if ocr:
page_list = Path(directory) / "pages.txt"
if any("\n" in str(page) or "\r" in str(page) for page in prepared):
raise ValueError("Das Scan-Arbeitsverzeichnis darf keinen Zeilenumbruch enthalten")
page_list.write_text("\n".join(map(str, prepared)) + "\n", encoding="utf8")
prefix = Path(directory) / "searchable"
run_ocr_command(["tesseract", str(page_list), str(prefix), "-l", ocr_language,
"--dpi", str(round(resolution)), "pdf"])
searchable = prefix.with_suffix(".pdf")
with PdfParser.PdfParser(filename=str(searchable)) as pdf:
if len(pdf.pages) != len(inputs):
raise RuntimeError("OCR-PDF ist unvollständig; Rohscans bleiben erhalten")
searchable.replace(partial)
partial.replace(output)
finally:
partial.unlink(missing_ok=True)
return {"pageCount": len(inputs), "warnings": warnings}
def interrupted(*_):
raise SystemExit("Scan-Verarbeitung abgebrochen")
def main():
# Let finally blocks stop Tesseract and remove incomplete PDFs on agent timeout.
signal.signal(signal.SIGTERM, interrupted)
parser = argparse.ArgumentParser(description="Scan-Seiten zu einer Datei zusammenführen")
parser.add_argument("--inputs", nargs="+")
parser.add_argument("--output")
parser.add_argument("--resolution", type=float, default=300)
parser.add_argument("--profile", choices=["document", "receipt", "raw"], default="document")
parser.add_argument("--postprocess", action="store_true")
parser.add_argument("--strict", action="store_true")
parser.add_argument("--background-cleanup", action="store_true")
parser.add_argument("--ocr", action="store_true")
parser.add_argument("--ocr-language", default="deu+eng")
parser.add_argument("--check-runtime", action="store_true")
args = parser.parse_args()
if args.check_runtime:
if args.background_cleanup or (args.postprocess and args.strict):
import cv2, numpy
if args.ocr:
check_ocr(args.ocr_language)
print(json.dumps({"ready": True}))
return
if not args.inputs or not args.output:
parser.error("--inputs und --output sind erforderlich")
print(json.dumps(create_document(args.inputs, args.output, args.resolution, args.postprocess, args.profile,
args.strict, args.ocr, args.ocr_language, args.background_cleanup)))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,26 @@
#!/usr/bin/env sh
set -eu
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
AGENT_DIR="$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)"
VENV_DIR="${FEDEO_SCAN_POSTPROCESS_VENV:-$AGENT_DIR/.venv-opencv}"
PYTHON_BIN="${PYTHON:-python3}"
echo "FEDEO OpenCV-Umgebung wird vorbereitet"
echo "Agent: $AGENT_DIR"
echo "Venv: $VENV_DIR"
if ! command -v "$PYTHON_BIN" >/dev/null 2>&1; then
echo "Fehler: $PYTHON_BIN wurde nicht gefunden." >&2
exit 1
fi
"$PYTHON_BIN" -m venv "$VENV_DIR"
"$VENV_DIR/bin/python" -m pip install --upgrade pip
"$VENV_DIR/bin/python" -m pip install -r "$AGENT_DIR/requirements-opencv.txt"
"$VENV_DIR/bin/python" -c "import cv2, PIL, numpy; print('OpenCV OK')"
echo
echo "Fertig. Verwende in .env:"
echo "FEDEO_SCAN_POSTPROCESS=true"
echo "FEDEO_SCAN_POSTPROCESS_PYTHON=$VENV_DIR/bin/python"

View File

@@ -0,0 +1,71 @@
import { readFile, stat } from "node:fs/promises"
import { basename } from "node:path"
import { AgentConfig, AgentHeartbeat, NextScanJobResponse, ScanResult } from "./types.js"
export class FedeoApi {
constructor(private readonly config: AgentConfig) {}
private url(path: string) {
return `${this.config.fedeoUrl}${path}`
}
private headers(extra?: HeadersInit): HeadersInit {
return {
"X-Agent-Token": this.config.agentToken,
...extra,
}
}
private async request<T>(path: string, init: RequestInit = {}, timeoutMs = 30_000): Promise<T> {
const response = await fetch(this.url(path), {
...init,
headers: this.headers(init.headers),
signal: AbortSignal.timeout(timeoutMs),
})
if (!response.ok) {
const body = await response.text().catch(() => "")
throw new Error(`${init.method || "GET"} ${path} fehlgeschlagen: ${response.status} ${body}`)
}
return await response.json() as T
}
heartbeat(payload: AgentHeartbeat) {
return this.request<{ status: string; pendingScanJobs: number }>("/instance-agent/heartbeat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
})
}
nextScanJob() {
return this.request<NextScanJobResponse>("/instance-agent/scan-jobs/next")
}
updateScanJobStatus(jobId: string, status: "running" | "failed" | "canceled", message?: string) {
return this.request(`/instance-agent/scan-jobs/${jobId}/status`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ status, message }),
})
}
async uploadScan(jobId: string, result: ScanResult) {
if ((await stat(result.path)).size > 100 * 1024 * 1024) {
throw new Error("Die Scan-Datei überschreitet das Upload-Limit von 100 MiB. Bitte den Stapel aufteilen oder die Auflösung reduzieren.")
}
const form = new FormData()
const fileBuffer = await readFile(result.path)
const file = new File([fileBuffer], result.filename || basename(result.path), {
type: result.mimeType,
})
form.append("file", file)
return this.request(`/instance-agent/scan-jobs/${jobId}/upload`, {
method: "POST",
body: form,
}, 120_000)
}
}

View File

@@ -0,0 +1,65 @@
import { spawn } from "node:child_process"
export type CommandResult = {
stdout: string
stderr: string
code: number
}
export const commandExists = (command: string) =>
new Promise<boolean>((resolve) => {
const child = spawn("sh", ["-c", 'command -v "$1" >/dev/null 2>&1', "--", command])
child.on("error", () => resolve(false))
child.on("close", (code) => resolve(code === 0))
})
export const runCommand = (
command: string,
args: string[],
options: { timeoutMs?: number; cwd?: string } = {}
) =>
new Promise<CommandResult>((resolve, reject) => {
const child = spawn(command, args, {
stdio: ["ignore", "pipe", "pipe"],
cwd: options.cwd,
})
const stdout: Buffer[] = []
const stderr: Buffer[] = []
let timedOut = false
let killTimeout: ReturnType<typeof setTimeout> | undefined
const timeout = options.timeoutMs
? setTimeout(() => {
timedOut = true
child.kill("SIGTERM")
killTimeout = setTimeout(() => child.kill("SIGKILL"), 2000)
}, options.timeoutMs)
: null
child.stdout.on("data", (chunk) => stdout.push(Buffer.from(chunk)))
child.stderr.on("data", (chunk) => stderr.push(Buffer.from(chunk)))
child.on("error", (error) => {
if (timeout) clearTimeout(timeout)
if (killTimeout) clearTimeout(killTimeout)
reject(error)
})
child.on("close", (code, signal) => {
if (timeout) clearTimeout(timeout)
if (killTimeout) clearTimeout(killTimeout)
if (timedOut) {
reject(new Error(`${command} wurde nach ${options.timeoutMs} ms beendet`))
return
}
if (signal) {
reject(new Error(`${command} wurde durch ${signal} beendet`))
return
}
resolve({
stdout: Buffer.concat(stdout).toString("utf8"),
stderr: Buffer.concat(stderr).toString("utf8"),
code: code ?? 1,
})
})
})

View File

@@ -0,0 +1,72 @@
import path from "node:path"
import os from "node:os"
import { existsSync } from "node:fs"
import { fileURLToPath } from "node:url"
import { AgentConfig } from "./types.js"
import { loadDotEnv } from "./env.js"
const currentFile = fileURLToPath(import.meta.url)
const agentRoot = path.resolve(path.dirname(currentFile), "..")
const optional = (value: string | undefined) => {
const trimmed = value?.trim()
return trimmed ? trimmed : undefined
}
const numberFromEnv = (value: string | undefined, fallback: number) => {
if (!value) return fallback
const parsed = Number(value)
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback
}
const scanFormatFromEnv = (value: string | undefined): AgentConfig["scanFormat"] => {
if (value === "png" || value === "tiff" || value === "pdf") return value
return "pdf"
}
const booleanFromEnv = (value: string | undefined, fallback: boolean) => {
if (!value) return fallback
return ["1", "true", "yes", "ja", "on"].includes(value.trim().toLowerCase())
}
const postprocessProfileFromEnv = (value: string | undefined): AgentConfig["postprocessProfile"] => {
if (value === "document" || value === "receipt" || value === "raw") return value
return "document"
}
const defaultPostprocessPython = () => {
const localVenvPython = path.join(agentRoot, ".venv-opencv", "bin", "python")
return existsSync(localVenvPython) ? localVenvPython : "python3"
}
export const loadConfig = (): AgentConfig => {
loadDotEnv(process.env.FEDEO_AGENT_ENV || ".env")
const fedeoUrl = optional(process.env.FEDEO_URL)
const agentToken = optional(process.env.FEDEO_AGENT_TOKEN)
if (!fedeoUrl) throw new Error("FEDEO_URL fehlt")
if (!agentToken) throw new Error("FEDEO_AGENT_TOKEN fehlt")
return {
fedeoUrl: fedeoUrl.replace(/\/+$/, ""),
agentToken,
pollSeconds: numberFromEnv(process.env.FEDEO_POLL_SECONDS, 5),
workDir: optional(process.env.FEDEO_WORK_DIR) || path.join(os.tmpdir(), "fedeo-device-agent"),
scannerName: optional(process.env.FEDEO_SCANNER_NAME),
printerName: optional(process.env.FEDEO_PRINTER_NAME),
scanFormat: scanFormatFromEnv(process.env.FEDEO_SCAN_FORMAT),
scanResolution: numberFromEnv(process.env.FEDEO_SCAN_RESOLUTION, 300),
scanMode: optional(process.env.FEDEO_SCAN_MODE) || "Color",
scanSource: optional(process.env.FEDEO_SCAN_SOURCE),
scanTimeoutSeconds: numberFromEnv(process.env.FEDEO_SCAN_TIMEOUT_SECONDS, 900),
scanPostprocess: booleanFromEnv(process.env.FEDEO_SCAN_POSTPROCESS, false),
scanBackgroundCleanup: booleanFromEnv(process.env.FEDEO_SCAN_BACKGROUND_CLEANUP, true),
scanOcr: booleanFromEnv(process.env.FEDEO_SCAN_OCR, true),
scanOcrLanguage: optional(process.env.FEDEO_SCAN_OCR_LANGUAGE) || "deu+eng",
postprocessProfile: postprocessProfileFromEnv(process.env.FEDEO_SCAN_POSTPROCESS_PROFILE),
postprocessPython: optional(process.env.FEDEO_SCAN_POSTPROCESS_PYTHON) || defaultPostprocessPython(),
postprocessStrict: booleanFromEnv(process.env.FEDEO_SCAN_POSTPROCESS_STRICT, false),
}
}

View File

@@ -0,0 +1,32 @@
import { readFileSync, existsSync } from "node:fs"
const parseEnvLine = (line: string) => {
const trimmed = line.trim()
if (!trimmed || trimmed.startsWith("#")) return null
const separator = trimmed.indexOf("=")
if (separator === -1) return null
const key = trimmed.slice(0, separator).trim()
let value = trimmed.slice(separator + 1).trim()
if (
(value.startsWith("\"") && value.endsWith("\"")) ||
(value.startsWith("'") && value.endsWith("'"))
) {
value = value.slice(1, -1)
}
return { key, value }
}
export const loadDotEnv = (path = ".env") => {
if (!existsSync(path)) return
const content = readFileSync(path, "utf8")
for (const line of content.split(/\r?\n/)) {
const parsed = parseEnvLine(line)
if (!parsed) continue
if (process.env[parsed.key] === undefined) process.env[parsed.key] = parsed.value
}
}

View File

@@ -0,0 +1,30 @@
const timestamp = () => new Date().toISOString()
export const log = {
info(message: string, meta?: unknown) {
if (meta === undefined) {
console.log(`[${timestamp()}] INFO ${message}`)
return
}
console.log(`[${timestamp()}] INFO ${message}`, meta)
},
warn(message: string, meta?: unknown) {
if (meta === undefined) {
console.warn(`[${timestamp()}] WARN ${message}`)
return
}
console.warn(`[${timestamp()}] WARN ${message}`, meta)
},
error(message: string, meta?: unknown) {
if (meta === undefined) {
console.error(`[${timestamp()}] ERROR ${message}`)
return
}
console.error(`[${timestamp()}] ERROR ${message}`, meta)
},
}

View File

@@ -0,0 +1,135 @@
#!/usr/bin/env node
import os from "node:os"
import path from "node:path"
import { rm } from "node:fs/promises"
import { FedeoApi } from "./api.js"
import { loadConfig } from "./config.js"
import { log } from "./logger.js"
import { listPrinters } from "./print/cups.js"
import { hasSane, listScanners, runScan } from "./scan/sane.js"
import { processingCapabilities } from "./scan/postprocess.js"
import { AgentHeartbeat } from "./types.js"
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
const stringifyError = (error: unknown) => {
if (error instanceof Error) return error.message
return String(error)
}
const main = async () => {
const config = loadConfig()
const api = new FedeoApi(config)
const processing = await processingCapabilities(config)
log.info("FEDEO Geräte-Agent startet", {
platform: process.platform,
workDir: config.workDir,
pollSeconds: config.pollSeconds,
})
while (true) {
try {
const scannerNames = await listScanners().catch((error) => {
log.warn("Scanner-Erkennung fehlgeschlagen", stringifyError(error))
return []
})
const printerNames = await listPrinters().catch(() => [])
const scanAvailable = await hasSane()
const heartbeatPayload: AgentHeartbeat = {
capabilities: {
scan: scanAvailable,
...processing,
print: printerNames.length > 0,
platform: process.platform,
},
scannerNames,
printerNames,
debugInfo: {
hostname: os.hostname(),
release: os.release(),
arch: os.arch(),
node: process.version,
uptimeSeconds: Math.round(os.uptime()),
},
}
const heartbeat = await api.heartbeat(heartbeatPayload)
if (heartbeat.pendingScanJobs > 0) {
log.info(`${heartbeat.pendingScanJobs} Scan-Auftrag/Aufträge warten`)
}
const next = await api.nextScanJob()
if (!next.job) {
await sleep(config.pollSeconds * 1000)
continue
}
log.info("Scan-Auftrag wird ausgeführt", {
jobId: next.job.id,
tenantId: next.job.tenantId,
scannerName: next.job.scannerName || config.scannerName || "default",
})
// Keep online status fresh during long scans without probing an occupied USB scanner.
let heartbeatRunning = false
const heartbeatTimer = setInterval(async () => {
if (heartbeatRunning) return
heartbeatRunning = true
try {
await api.heartbeat(heartbeatPayload)
} catch (error) {
log.warn("Heartbeat während Scan fehlgeschlagen", stringifyError(error))
} finally {
heartbeatRunning = false
}
}, 30_000)
try {
await api.updateScanJobStatus(next.job.id, "running")
const jobId = next.job.id
const reportProgress = async (message: string) => {
await api.updateScanJobStatus(jobId, "running", message).catch((error) => {
log.warn("Scan-Status konnte nicht übertragen werden", stringifyError(error))
})
}
const scanResult = await runScan(config, next.job, reportProgress)
await reportProgress(`${scanResult.pageCount} Seiten gescannt. ${scanResult.warnings.join(" ")}`.trim())
try {
await api.uploadScan(jobId, scanResult)
} catch (error) {
throw new Error(`${stringifyError(error)} Scan-Datei bleibt zur Wiederherstellung unter ${scanResult.path}.`)
}
await rm(path.dirname(scanResult.path), { recursive: true, force: true }).catch((error) => {
log.warn("Scan gespeichert; temporäre Dateien konnten nicht entfernt werden", stringifyError(error))
})
log.info("Scan-Auftrag abgeschlossen", {
jobId: next.job.id,
file: scanResult.filename,
pages: scanResult.pageCount,
})
} catch (error) {
const message = stringifyError(error)
log.error("Scan-Auftrag fehlgeschlagen", {
jobId: next.job.id,
message,
})
await api.updateScanJobStatus(next.job.id, "failed", message)
} finally {
clearInterval(heartbeatTimer)
}
} catch (error) {
log.error("Agent-Schleife fehlgeschlagen", stringifyError(error))
await sleep(config.pollSeconds * 1000)
}
}
}
main().catch((error) => {
log.error("Agent konnte nicht gestartet werden", stringifyError(error))
process.exit(1)
})

View File

@@ -0,0 +1,15 @@
import { commandExists, runCommand } from "../commands.js"
export const hasCups = () => commandExists("lpstat")
export const listPrinters = async () => {
if (!await hasCups()) return []
const result = await runCommand("lpstat", ["-p"], { timeoutMs: 10_000 })
if (result.code !== 0) return []
return result.stdout
.split(/\r?\n/)
.map((line) => line.match(/^printer\s+(\S+)/)?.[1])
.filter((printer): printer is string => Boolean(printer))
}

View File

@@ -0,0 +1,67 @@
import path from "node:path"
import { fileURLToPath } from "node:url"
import { AgentConfig, ScanResult } from "../types.js"
import { runCommand } from "../commands.js"
const agentRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..")
const documentScript = path.join(agentRoot, "scripts/scan_document.py")
type ProcessingOptions = { ocr: boolean; ocrLanguage: string; backgroundCleanup: boolean }
export const checkScanRuntime = async (config: AgentConfig, postprocess: boolean, options: ProcessingOptions) => {
const args = [documentScript, "--check-runtime", "--ocr-language", options.ocrLanguage]
if (postprocess) args.push("--postprocess")
if (config.postprocessStrict) args.push("--strict")
if (options.backgroundCleanup) args.push("--background-cleanup")
if (options.ocr) args.push("--ocr")
try {
const result = await runCommand(config.postprocessPython, args, { timeoutMs: 10_000 })
if (result.code === 0) return
throw new Error(result.stderr.trim())
} catch (error) {
// Report missing runtimes before the scanner consumes any paper.
const detail = error instanceof Error ? error.message : String(error)
throw new Error("Scan-Verarbeitung nicht verfügbar. Bitte den Agenten mit Python/Pillow, OpenCV und Tesseract samt OCR-Sprachpaketen installieren. " + detail)
}
}
export const processingCapabilities = async (config: AgentConfig) => {
const available = async (options: ProcessingOptions) => {
try { await checkScanRuntime(config, false, options); return true } catch { return false }
}
const [ocr, backgroundCleanup] = await Promise.all([
available({ ocr: true, ocrLanguage: config.scanOcrLanguage, backgroundCleanup: false }),
available({ ocr: false, ocrLanguage: config.scanOcrLanguage, backgroundCleanup: true }),
])
return { ocr, backgroundCleanup }
}
export const createScanDocument = async (
config: AgentConfig,
pages: string[],
outputPath: string,
resolution: number,
postprocess: boolean,
profile: AgentConfig["postprocessProfile"],
options: ProcessingOptions
): Promise<ScanResult> => {
const args = [documentScript, "--output", outputPath, "--resolution", String(resolution), "--profile", profile]
if (postprocess) args.push("--postprocess")
if (config.postprocessStrict) args.push("--strict")
if (options.backgroundCleanup) args.push("--background-cleanup")
if (options.ocr) args.push("--ocr", "--ocr-language", options.ocrLanguage)
args.push("--inputs", ...pages)
const result = await runCommand(config.postprocessPython, args, {
timeoutMs: config.scanTimeoutSeconds * 1000,
})
if (result.code !== 0) throw new Error(result.stderr || "Scan-Datei konnte nicht erstellt werden")
const details = JSON.parse(result.stdout) as { pageCount: number; warnings: string[] }
return {
path: outputPath,
filename: path.basename(outputPath),
mimeType: outputPath.endsWith(".pdf") ? "application/pdf" : outputPath.endsWith(".png") ? "image/png" : "image/tiff",
...details,
}
}

View File

@@ -0,0 +1,125 @@
import { mkdir, mkdtemp, readdir, stat } from "node:fs/promises"
import path from "node:path"
import { AgentConfig, ScanJob, ScanResult } from "../types.js"
import { commandExists, runCommand } from "../commands.js"
import { checkScanRuntime, createScanDocument } from "./postprocess.js"
const stringSetting = (settings: Record<string, unknown>, key: string) => {
const value = settings[key]
return typeof value === "string" && value.trim() ? value.trim() : undefined
}
const booleanSetting = (settings: Record<string, unknown>, key: string, fallback: boolean) => {
const value = settings[key]
if (typeof value === "boolean") return value
if (typeof value === "string") return ["1", "true", "yes", "ja", "on"].includes(value.trim().toLowerCase())
return fallback
}
export const hasSane = () => commandExists("scanimage")
export const listScanners = async () => {
if (!await hasSane()) return []
// SANE also probes network backends; these can take more than ten seconds
// even when the USB scanner is already available.
const result = await runCommand("scanimage", ["-L"], { timeoutMs: 30_000 })
if (result.code !== 0) return []
return result.stdout.split(/\r?\n/)
.map((line) => line.trim().match(/^device `([^']+)'/)?.[1])
.filter((device): device is string => Boolean(device))
}
export const runScan = async (
config: AgentConfig,
job: ScanJob,
reportProgress: (message: string) => Promise<void> = async () => {}
): Promise<ScanResult> => {
if (!await hasSane()) throw new Error("scanimage ist nicht installiert oder nicht im PATH")
const settings = job.settings || {}
const format = stringSetting(settings, "format") || config.scanFormat
if (!["pdf", "png", "tiff"].includes(format)) throw new Error("Scan-Format muss PDF, PNG oder TIFF sein")
const resolution = Number(settings.resolution ?? config.scanResolution)
if (!Number.isFinite(resolution) || resolution < 75 || resolution > 1200) {
throw new Error("Die Scan-Auflösung muss zwischen 75 und 1200 dpi liegen")
}
const mode = stringSetting(settings, "mode") || config.scanMode
const source = stringSetting(settings, "source") || config.scanSource
const scannerName = job.scannerName || config.scannerName
const paperSize = stringSetting(settings, "paperSize") || "auto"
if (!["auto", "A4", "Letter"].includes(paperSize)) throw new Error("Unbekanntes Papierformat")
const batch = Boolean(source && /adf|document feeder/i.test(source))
if (batch && format !== "pdf") throw new Error("Für Einzug- und Duplex-Scans bitte PDF als Format wählen")
const postprocess = booleanSetting(settings, "postprocess", config.scanPostprocess)
const profile = stringSetting(settings, "postprocessProfile") || config.postprocessProfile
if (!["document", "receipt", "raw"].includes(profile)) throw new Error("Unbekanntes Nachbearbeitungsprofil")
const processing = {
backgroundCleanup: booleanSetting(settings, "backgroundCleanup", config.scanBackgroundCleanup),
ocr: format === "pdf" && booleanSetting(settings, "ocr", config.scanOcr),
ocrLanguage: stringSetting(settings, "ocrLanguage") || config.scanOcrLanguage,
}
await checkScanRuntime(config, postprocess, processing)
// Each physical scan has its own directory. A filename cannot escape it or overwrite another job.
await mkdir(config.workDir, { recursive: true, mode: 0o700 })
const jobDir = await mkdtemp(path.join(path.resolve(config.workDir), "scan-"))
const requested = path.basename((job.requestedFilename || "scan").replace(/\\/g, "/"))
const stem = requested.replace(/\.[^.]*$/, "").replace(/[\x00-\x1f]/g, "").trim() || "scan"
const outputPath = path.join(jobDir, `${stem}.${format}`)
try {
// Device/source come first: changing source can change the remaining SANE options.
const args: string[] = []
if (scannerName) args.push("--device-name", scannerName)
if (source) args.push("--source", source)
args.push("--mode", mode, "--resolution", String(resolution), "--format=png")
if (paperSize !== "auto") {
const [width, height] = paperSize === "A4" ? [210, 297] : [215.9, 279.4]
if (scannerName?.startsWith("fujitsu:")) {
args.push("--page-width", String(width), "--page-height", String(height))
}
args.push("-l", "0", "-t", "0", "-x", String(width), "-y", String(height))
}
if (batch) {
// Relative pattern avoids interpreting '%' in a user-configured work directory.
args.push("--batch=page-%06d.png", "--batch-start=1", "--batch-increment=1")
} else {
args.push("--output-file", "page-000001.png")
}
await reportProgress(batch ? "Dokumente werden eingezogen und gescannt..." : "Seite wird gescannt...")
const result = await runCommand("scanimage", args, {
cwd: jobDir,
timeoutMs: config.scanTimeoutSeconds * 1000,
})
// SANE_STATUS_NO_DOCS (7) is the expected end of an unlimited ADF batch.
// Never turn paper jams, I/O errors or canceled scans into a successful partial upload.
if (result.code !== 0 && !(batch && result.code === 7)) {
throw new Error(result.stderr.trim() || `scanimage wurde mit Code ${result.code} beendet`)
}
const names = (await readdir(jobDir))
.filter((name) => /^page-\d+\.png$/.test(name))
.sort((a, b) => Number(a.match(/\d+/)![0]) - Number(b.match(/\d+/)![0]))
const pages: string[] = []
for (const [index, name] of names.entries()) {
const page = path.join(jobDir, name)
// Some scanimage versions leave a zero-byte file for the final NO_DOCS attempt.
if ((await stat(page)).size === 0) {
if (batch && result.code === 7 && index === names.length - 1) continue
throw new Error(`Unvollständige Scan-Seite: ${name}`)
}
if (Number(name.match(/\d+/)![0]) !== index + 1) throw new Error("Im Scan fehlen Seiten")
pages.push(page)
}
if (!pages.length) throw new Error("Keine Seiten gescannt. Bitte Papier in den Einzug legen.")
if (source?.toLowerCase().includes("duplex") && pages.length % 2 !== 0) {
throw new Error("Der Duplex-Scan ist unvollständig: Zu einer Vorderseite fehlt die Rückseite.")
}
await reportProgress(`${pages.length} Seiten gescannt. ${processing.ocr ? "Durchsuchbares PDF mit OCR wird erstellt..." : "Datei wird erstellt..."}`)
return await createScanDocument(config, pages, outputPath, resolution, postprocess, profile as AgentConfig["postprocessProfile"], processing)
} catch (error) {
const message = error instanceof Error ? error.message : String(error)
throw new Error(`${message} Rohscans bleiben zur Wiederherstellung in ${jobDir}.`)
}
}

View File

@@ -0,0 +1,56 @@
export type AgentConfig = {
fedeoUrl: string
agentToken: string
pollSeconds: number
workDir: string
scannerName?: string
printerName?: string
scanFormat: "pdf" | "png" | "tiff"
scanResolution: number
scanMode: string
scanSource?: string
scanTimeoutSeconds: number
scanPostprocess: boolean
scanBackgroundCleanup: boolean
scanOcr: boolean
scanOcrLanguage: string
postprocessProfile: "document" | "receipt" | "raw"
postprocessPython: string
postprocessStrict: boolean
}
export type AgentHeartbeat = {
capabilities: {
scan: boolean
print: boolean
ocr: boolean
backgroundCleanup: boolean
platform: NodeJS.Platform
}
scannerNames: string[]
printerNames: string[]
debugInfo: Record<string, unknown>
}
export type ScanJob = {
id: string
tenantId: number
agentId: string
status: string
scannerName?: string | null
requestedFilename?: string | null
settings?: Record<string, unknown>
target?: Record<string, unknown>
}
export type NextScanJobResponse = {
job: ScanJob | null
}
export type ScanResult = {
path: string
filename: string
mimeType: string
pageCount: number
warnings: string[]
}

View File

@@ -0,0 +1,15 @@
[Unit]
Description=FEDEO Geräte-Agent
After=network-online.target
Wants=network-online.target
[Service]
EnvironmentFile=/etc/fedeo-device-agent/config.env
WorkingDirectory=/opt/fedeo-device-agent
ExecStart=/usr/bin/node /opt/fedeo-device-agent/dist/main.js
Restart=always
RestartSec=5
User=fedeo-agent
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.fedeo.device-agent</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/node</string>
<string>/opt/fedeo-device-agent/dist/main.js</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>FEDEO_AGENT_ENV</key>
<string>/opt/fedeo-device-agent/.env</string>
</dict>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/fedeo-device-agent.log</string>
<key>StandardErrorPath</key>
<string>/tmp/fedeo-device-agent.err.log</string>
</dict>
</plist>

View File

@@ -0,0 +1,91 @@
import assert from 'node:assert/strict'
import test from 'node:test'
import { readFile, writeFile, mkdir, mkdtemp, stat, rm } from 'node:fs/promises'
import path from 'node:path'
import os from 'node:os'
import { execFile } from 'node:child_process'
import { promisify } from 'node:util'
import { fileURLToPath } from 'node:url'
import { agentBackendUrl, agentSetupReady, renderAgentInstaller } from '../../../frontend/utils/agentInstaller.mjs'
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
const bundle = JSON.parse(await readFile(path.resolve(root, '../../frontend/assets/device-agent/bundle.json'), 'utf8'))
const agentId = 'b48c0e33-1abd-4b11-89fa-1bb7b39a3057'
const token = 'fedeo_agent_' + 'a'.repeat(64)
const options = { agentId, token, backendUrl: 'https://fedeo.example.com/backend', autostart: true }
const execute = promisify(execFile)
const hasSystemdAnalyze = process.platform === 'linux' && await execute('systemd-analyze', ['--version'])
.then(() => true, error => { if (error.code === 'ENOENT') return false; throw error })
test('backend URLs preserve reverse-proxy paths and reject credentials or non-HTTP protocols', () => {
assert.equal(agentBackendUrl('/backend/', 'https://fedeo.example.com'), options.backendUrl)
assert.equal(agentBackendUrl('', 'http://localhost:3100'), 'http://localhost:3100')
assert.throws(() => agentBackendUrl('javascript:alert(1)'))
assert.throws(() => agentBackendUrl('https://user:secret@example.com'))
assert.throws(() => agentBackendUrl('https://example.com?token=secret'))
})
test('installer validates tokens and identities before generating executable content', () => {
assert.throws(() => renderAgentInstaller(bundle, { ...options, token: 'not-a-token' }))
assert.throws(() => renderAgentInstaller(bundle, { ...options, agentId: "x'; touch /tmp/unwanted; '" }))
assert.throws(() => renderAgentInstaller(bundle, { ...options, backendUrl: 'https://example.com/\nFEDEO_AGENT_TOKEN=bad' }))
const script = renderAgentInstaller(bundle, options)
assert.ok(!script.includes('@@'))
})
test('connection readiness requires an active agent and a fresh heartbeat for this setup', () => {
const now = Date.now()
assert.equal(agentSetupReady({ active: true, lastSeenAt: new Date(now).toISOString() }, now - 1000, now), true)
assert.equal(agentSetupReady({ active: false, lastSeenAt: new Date(now).toISOString() }, 0, now), false)
assert.equal(agentSetupReady({ active: true, lastSeenAt: new Date(now - 5000).toISOString() }, now - 1000, now), false)
assert.equal(agentSetupReady({ active: true, lastSeenAt: 'invalid' }), false)
})
for (const start of [false, true]) {
test('downloaded installer writes runtime and credentials; start=' + start, { skip: process.platform !== 'linux' }, async (t) => {
const temp = await mkdtemp(path.join(os.tmpdir(), 'fedeo-installer-test-'))
t.after(() => rm(temp, { recursive: true, force: true }))
const bin = path.join(temp, 'bin')
await mkdir(bin)
// No package manager, scanner or real systemd command may run during this test.
await writeFile(path.join(bin, 'sudo'), '#!/bin/sh\nexit 99\n', { mode: 0o755 })
await writeFile(path.join(bin, 'scanimage'), '#!/bin/sh\nexit 0\n', { mode: 0o755 })
await writeFile(path.join(bin, 'id'), '#!/bin/sh\nprintf "1000\\n"\n', { mode: 0o755 })
await writeFile(path.join(bin, 'systemctl'), '#!/bin/sh\nprintf "%s\\n" "$*" >> "$FEDEO_TEST_SYSTEMD_LOG"\n', { mode: 0o755 })
const realPython = (await execute('sh', ['-c', 'command -v python3'])).stdout.trim()
await writeFile(path.join(bin, 'python3'), '#!/bin/sh\nif [ "$1" = "-c" ] && [ "$2" = "import PIL, cv2, numpy" ]; then exit 0; fi\nexec "$FEDEO_TEST_PYTHON" "$@"\n', { mode: 0o755 })
await writeFile(path.join(bin, 'tesseract'), '#!/bin/sh\nprintf "deu\\neng\\n"\n', { mode: 0o755 })
const env = {
...process.env, PATH: bin + ':' + process.env.PATH,
XDG_DATA_HOME: path.join(temp, 'data with spaces %'),
XDG_CONFIG_HOME: path.join(temp, 'config'), XDG_STATE_HOME: path.join(temp, 'state'),
FEDEO_TEST_SYSTEMD_LOG: path.join(temp, 'systemd.log'),
FEDEO_TEST_PYTHON: realPython,
}
const scriptPath = path.join(temp, 'install.sh')
await writeFile(scriptPath, renderAgentInstaller(bundle, options))
await execute('bash', ['-n', scriptPath])
const { stdout: output } = await execute('bash', [scriptPath, ...(start ? [] : ['--no-start'])], { env, encoding: 'utf8' })
const agentDir = path.join(env.XDG_DATA_HOME, 'fedeo-device-agent', agentId)
const configPath = path.join(env.XDG_CONFIG_HOME, 'fedeo-device-agent', agentId + '.env')
const config = await readFile(configPath, 'utf8')
assert.ok(config.includes('FEDEO_URL=' + options.backendUrl + '\n'))
assert.ok(config.includes('FEDEO_AGENT_TOKEN=' + token + '\n'))
assert.equal((await stat(configPath)).mode & 0o777, 0o600)
assert.ok(!output.includes(token))
for (const [file, encoded] of Object.entries(bundle.files)) {
assert.equal((await readFile(path.join(agentDir, file))).toString('base64'), encoded)
}
const unitPath = path.join(env.XDG_CONFIG_HOME, 'systemd/user', 'fedeo-device-agent-' + agentId + '.service')
const unit = await readFile(unitPath, 'utf8')
assert.ok(unit.includes('data with spaces %%'))
assert.ok(!unit.includes(token))
await t.test('systemd accepts the generated service, including a working directory with spaces and percent signs', { skip: !hasSystemdAnalyze }, async () => {
await execute('systemd-analyze', ['--user', 'verify', unitPath])
})
const calls = await readFile(env.FEDEO_TEST_SYSTEMD_LOG, 'utf8')
assert.equal(calls.includes('--user enable fedeo-device-agent-'), start)
assert.equal(calls.includes('--user restart fedeo-device-agent-'), start)
assert.equal(calls.includes('--user stop fedeo-device-agent-'), start)
})
}

View File

@@ -0,0 +1,184 @@
import assert from "node:assert/strict"
import test, { TestContext } from "node:test"
import os from "node:os"
import path from "node:path"
import { chmod, mkdtemp, readFile, readdir, rm, writeFile } from "node:fs/promises"
import { listScanners, runScan } from "../src/scan/sane.js"
import { commandExists, runCommand } from "../src/commands.js"
import { AgentConfig, ScanJob } from "../src/types.js"
const fakeScanner = `#!/usr/bin/env python3
import json, os, sys, time
from pathlib import Path
from PIL import Image
args = sys.argv[1:]
Path(os.environ['SCAN_TEST_CALL']).write_text(json.dumps(args))
if args == ['-L']:
time.sleep(float(os.environ.get('SCAN_TEST_DISCOVERY_DELAY', '0')))
print("device " + chr(96) + "fujitsu:ScanSnap iX1600:test' is a FUJITSU scanner")
print("device " + chr(96) + "airscan:test' is a network scanner")
sys.exit(int(os.environ.get('SCAN_TEST_EXIT', '0')))
batch = next((arg.split('=', 1)[1] for arg in args if arg.startswith('--batch=')), None)
single = args[args.index('--output-file') + 1] if '--output-file' in args else None
count = int(os.environ.get('SCAN_TEST_PAGES', '4')) if batch else 1
for index in range(1, count + 1):
target = batch % index if batch else single
Image.new('RGB', (100 + index, 200 + index), (index * 10, 20, 30)).save(target)
if batch and os.environ.get('SCAN_TEST_EMPTY_FINAL') == '1':
Path(batch % (count + 1)).touch()
if os.environ.get('SCAN_TEST_CORRUPT') == '1':
Path(batch % 2 if batch else single).write_bytes(b'not a PNG')
if os.environ.get('SCAN_TEST_EMPTY_MIDDLE') == '1':
Path(batch % 2).write_bytes(b'')
sys.stderr.write('simulated scanner status')
sys.exit(int(os.environ.get('SCAN_TEST_EXIT', '7' if batch else '0')))
`
const setup = async (t: TestContext) => {
const dir = await mkdtemp(path.join(os.tmpdir(), "fedeo-scan-test-"))
const oldEnv = { ...process.env }
t.after(async () => {
for (const key of Object.keys(process.env)) if (!(key in oldEnv)) delete process.env[key]
Object.assign(process.env, oldEnv)
await rm(dir, { recursive: true, force: true })
})
await writeFile(path.join(dir, "scanimage"), fakeScanner)
await chmod(path.join(dir, "scanimage"), 0o755)
process.env.PATH = `${dir}:${process.env.PATH}`
process.env.SCAN_TEST_CALL = path.join(dir, "call.json")
const config: AgentConfig = {
fedeoUrl: "https://example.invalid", agentToken: "test", pollSeconds: 5,
workDir: path.join(dir, "scans with 100% space"), scannerName: "fujitsu:ScanSnap iX1600:test",
scanFormat: "pdf", scanResolution: 300, scanMode: "Color", scanSource: "ADF Duplex",
scanTimeoutSeconds: 10, scanPostprocess: false, postprocessProfile: "document",
scanBackgroundCleanup: false, scanOcr: false, scanOcrLanguage: "deu+eng",
postprocessPython: "python3", postprocessStrict: false,
}
const job: ScanJob = { id: "test-job", tenantId: 1, agentId: "test-agent", status: "running", settings: { paperSize: "A4" } }
return { config, job, dir, args: async () => JSON.parse(await readFile(process.env.SCAN_TEST_CALL!, "utf8")) as string[] }
}
test("scanner discovery waits for network probes beyond the former ten-second limit", async (t) => {
await setup(t)
process.env.SCAN_TEST_DISCOVERY_DELAY = "10.2"
assert.deepEqual(await listScanners(), ["fujitsu:ScanSnap iX1600:test", "airscan:test"])
})
test("failed scanner discovery does not advertise devices from an unsuccessful command", async (t) => {
await setup(t)
process.env.SCAN_TEST_EXIT = "1"
assert.deepEqual(await listScanners(), [])
})
test("duplex batch saves all pages as PDF, accepts NO_DOCS and passes A4 geometry", async (t) => {
const { config, job, args } = await setup(t)
process.env.SCAN_TEST_EMPTY_FINAL = "1"
const progress: string[] = []
const result = await runScan(config, job, async (message) => { progress.push(message) })
assert.equal(result.pageCount, 4)
assert.equal(result.mimeType, "application/pdf")
assert.equal((await readFile(result.path)).subarray(0, 5).toString(), "%PDF-")
assert.deepEqual(result.warnings, [])
const call = await args()
assert.ok(call.includes("--batch=page-%06d.png"))
assert.ok(!call.includes("--output-file"))
assert.ok(!call.includes("--batch-double"))
assert.equal(call[call.indexOf("--source") + 1], "ADF Duplex")
assert.equal(call[call.indexOf("--page-height") + 1], "297")
assert.equal(call[call.indexOf("-y") + 1], "297")
assert.ok(progress.at(-1)?.startsWith("4 Seiten"))
})
test("empty ADF reports missing paper instead of creating an empty PDF", async (t) => {
const { config, job } = await setup(t)
process.env.SCAN_TEST_PAGES = "0"
process.env.SCAN_TEST_EMPTY_FINAL = "1"
await assert.rejects(runScan(config, job), /Keine Seiten gescannt/)
})
test("paper jam after partial capture fails and keeps raw pages for recovery", async (t) => {
const { config, job } = await setup(t)
process.env.SCAN_TEST_EXIT = "6"
await assert.rejects(runScan(config, job), /simulated scanner status.*Rohscans/)
const [jobDir] = await readdir(config.workDir)
assert.equal((await readdir(path.join(config.workDir, jobDir))).filter((name) => name.endsWith(".png")).length, 4)
})
test("odd duplex page count cannot silently lose a back side", async (t) => {
const { config, job } = await setup(t)
process.env.SCAN_TEST_PAGES = "3"
await assert.rejects(runScan(config, job), /Rückseite/)
})
test("ADF simplex keeps odd page counts and scanimage success is accepted", async (t) => {
const { config, job } = await setup(t)
process.env.SCAN_TEST_PAGES = "3"
process.env.SCAN_TEST_EXIT = "0"
job.settings!.source = "ADF Front"
assert.equal((await runScan(config, job)).pageCount, 3)
})
test("corrupt or empty interior pages fail instead of disappearing from a successful PDF", async (t) => {
const { config, job } = await setup(t)
process.env.SCAN_TEST_CORRUPT = "1"
await assert.rejects(runScan(config, job), /cannot identify image file/)
delete process.env.SCAN_TEST_CORRUPT
process.env.SCAN_TEST_EMPTY_MIDDLE = "1"
await assert.rejects(runScan(config, job), /Unvollständige Scan-Seite/)
})
test("non-PDF feeder output and invalid resolution are rejected before feeding paper", async (t) => {
const { config, job, args } = await setup(t)
job.settings!.format = "png"
await assert.rejects(runScan(config, job), /PDF/)
delete job.settings!.format
job.settings!.resolution = -300
await assert.rejects(runScan(config, job), /Auflösung/)
await assert.rejects(args(), /ENOENT/)
})
test("missing image runtime is detected before feeding paper", async (t) => {
const { config, job, args } = await setup(t)
config.postprocessPython = "/not-installed/python"
await assert.rejects(runScan(config, job), /Python\/Pillow/)
await assert.rejects(args(), /ENOENT/)
})
test("missing requested OCR language fails before the scanner consumes paper", async (t) => {
const { config, job, dir, args } = await setup(t)
const tesseract = path.join(dir, "tesseract")
await writeFile(tesseract, "#!/bin/sh\nprintf 'List of available languages (1):\\neng\\n'\n")
await chmod(tesseract, 0o755)
job.settings!.ocr = true
job.settings!.ocrLanguage = "deu+eng"
await assert.rejects(runScan(config, job), /OCR-Sprachpakete fehlen: deu/)
await assert.rejects(args(), /ENOENT/)
await assert.rejects(readdir(config.workDir), /ENOENT/)
})
test("single-page scans work without batch and requested paths cannot escape the job directory", async (t) => {
const { config, job, args } = await setup(t)
job.settings = { source: "Flatbed", format: "png" }
job.requestedFilename = "../../outside.pdf"
const first = await runScan(config, job)
const second = await runScan(config, job)
assert.equal(first.filename, "outside.png")
assert.equal(first.pageCount, 1)
assert.equal(first.mimeType, "image/png")
assert.ok(first.path.startsWith(`${config.workDir}${path.sep}`))
assert.notEqual(path.dirname(first.path), path.dirname(second.path))
assert.ok((await args()).includes("--output-file"))
assert.ok(!(await args()).some((arg) => arg.startsWith("--batch")))
})
test("a process terminated by a signal is never reported as a successful scan", async () => {
await assert.rejects(runCommand(process.execPath, ["-e", "process.kill(process.pid, 'SIGTERM')"]), /SIGTERM/)
})
test("a scan timeout terminates the child and reports failure", async () => {
await assert.rejects(runCommand(process.execPath, ["-e", "setInterval(() => {}, 1000)"], { timeoutMs: 50 }), /beendet/)
})
test("command discovery treats executable paths as data", async () => {
assert.equal(await commandExists("python3; exit 0"), false)
})

View File

@@ -0,0 +1,64 @@
import sys
import unittest
from pathlib import Path
import cv2
import numpy as np
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "scripts"))
from scan_background import whiten_background
class ScanBackgroundTest(unittest.TestCase):
def receipt(self, background=45, paper=245):
image = np.full((1600, 1200, 3), background, dtype=np.uint8)
image[120:1440, 360:820] = paper
for y in range(220, 1350, 70):
cv2.putText(image, "BON 12,34 EUR", (375, y), cv2.FONT_HERSHEY_SIMPLEX, .7, (20, 20, 20), 2)
cv2.rectangle(image, (400, 140), (780, 180), (40, 80, 210), -1)
return image
def test_receipt_on_dark_or_gray_backing_keeps_canvas_text_and_colored_logo(self):
for background in (35, 140):
image = self.receipt(background)
result = whiten_background(image)
self.assertEqual(result.shape, image.shape)
self.assertTrue(np.all(result[:80] == 255))
self.assertTrue(np.all(result[:, :250] == 255))
self.assertTrue(np.array_equal(result[120:1440, 360:820], image[120:1440, 360:820]))
def test_slanted_receipt_is_whitened_without_rotating_or_cropping(self):
image = np.full((1600, 1200, 3), 55, dtype=np.uint8)
polygon = np.array([[450, 100], [890, 155], [720, 1450], [280, 1390]])
cv2.fillPoly(image, [polygon], (245, 245, 245))
cv2.putText(image, "FEDEO", (470, 700), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 0), 3)
result = whiten_background(image)
self.assertEqual(result.shape, image.shape)
inside = np.zeros(image.shape[:2], dtype=np.uint8)
cv2.fillPoly(inside, [polygon], 255)
self.assertTrue(np.array_equal(result[inside > 0], image[inside > 0]))
self.assertTrue(np.all(result[:50] == 255))
def test_white_full_page_is_not_replaced_by_its_largest_text_box(self):
image = np.full((1600, 1200, 3), 255, dtype=np.uint8)
cv2.rectangle(image, (300, 400), (800, 1200), (30, 30, 30), 4)
cv2.putText(image, "Footer", (20, 1550), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2)
self.assertTrue(np.array_equal(whiten_background(image), image))
def test_slanted_receipt_retains_every_paper_edge_pixel_at_300_dpi(self):
image = np.full((3508, 2480, 3), 45, dtype=np.uint8)
polygon = np.array([[820, 200], [1700, 340], [1250, 3300], [380, 3160]])
cv2.fillPoly(image, [polygon], (245, 245, 245))
inside = np.zeros(image.shape[:2], dtype=np.uint8)
cv2.fillPoly(inside, [polygon], 255)
result = whiten_background(image)
self.assertTrue(np.array_equal(result[inside > 0], image[inside > 0]))
self.assertTrue(np.all(result[:50] == 255))
def test_blank_and_ambiguous_low_contrast_pages_remain_unchanged(self):
for image in [np.full((300, 200, 3), 245, dtype=np.uint8), self.receipt(215, 230)]:
self.assertTrue(np.array_equal(whiten_background(image), image))
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,93 @@
import sys
import tempfile
import unittest
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import patch
from PIL import Image, PdfParser
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "scripts"))
from scan_document import create_document
class ScanDocumentTest(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory()
self.addCleanup(self.temp.cleanup)
self.root = Path(self.temp.name)
def pages(self, count=4):
paths = []
for index in range(1, count + 1):
target = self.root / f"page-{index:06}.png"
# Distinct geometry identifies every front/back page and its order.
with Image.new("RGB", (100 + index, 200 + index), "white") as image:
image.save(target)
paths.append(target)
return paths
def assert_pdf(self, output, count, resolution=300):
with PdfParser.PdfParser(filename=str(output)) as pdf:
self.assertEqual(len(pdf.pages), count)
for index, reference in enumerate(pdf.pages, 1):
page = pdf.read_indirect(reference)
box = page[b"MediaBox"]
self.assertAlmostEqual(box[2], (100 + index) * 72 / resolution, places=4)
self.assertAlmostEqual(box[3], (200 + index) * 72 / resolution, places=4)
def test_twelve_pages_keep_front_back_order_blank_pages_and_scan_resolution(self):
output = self.root / "scan.pdf"
result = create_document(self.pages(12), output, 150)
self.assertEqual(result, {"pageCount": 12, "warnings": []})
self.assert_pdf(output, 12, 150)
def test_missing_opencv_still_creates_complete_pdf(self):
output = self.root / "scan.pdf"
with patch.dict(sys.modules, {"opencv_postprocess": None}):
result = create_document(self.pages(), output, 300, use_postprocess=True)
self.assertEqual(len(result["warnings"]), 1)
self.assert_pdf(output, 4)
def test_failed_correction_falls_back_per_page_without_losing_sides(self):
def correct(source, target, profile):
if source.name.endswith("000002.png"):
raise RuntimeError("correction failed")
target.write_bytes(source.read_bytes())
output = self.root / "scan.pdf"
with patch.dict(sys.modules, {"opencv_postprocess": SimpleNamespace(postprocess=correct)}):
result = create_document(self.pages(), output, 300, use_postprocess=True)
self.assertEqual(len(result["warnings"]), 1)
self.assertIn("Seite 2", result["warnings"][0])
self.assert_pdf(output, 4)
def test_strict_mode_does_not_silently_skip_missing_correction(self):
output = self.root / "scan.pdf"
with patch.dict(sys.modules, {"opencv_postprocess": None}):
with self.assertRaises(ImportError):
create_document(self.pages(), output, 300, use_postprocess=True, strict=True)
self.assertFalse(output.exists())
def test_corrupt_page_never_publishes_partial_pdf(self):
pages = self.pages()
pages[2].write_bytes(b"corrupt")
output = self.root / "scan.pdf"
with self.assertRaises(OSError):
create_document(pages, output, 300)
self.assertFalse(output.exists())
self.assertFalse((self.root / "scan.pdf.partial").exists())
self.assertTrue(all(page.exists() for page in pages))
def test_single_page_png_and_tiff_remain_supported(self):
pages = self.pages(1)
for extension in ["png", "tiff"]:
output = self.root / f"scan.{extension}"
create_document(pages, output, 150)
with Image.open(output) as image:
self.assertEqual(image.size, (101, 201))
self.assertAlmostEqual(image.info["dpi"][0], 150, delta=0.1)
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,71 @@
import shutil
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch
from PIL import Image, ImageDraw, ImageFont, PdfParser
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "scripts"))
from scan_document import create_document, check_ocr
class ScanOcrTest(unittest.TestCase):
def test_missing_language_is_reported_before_processing(self):
with patch("scan_document.run_ocr_command", return_value="List of available languages (1):\neng\n"):
with self.assertRaisesRegex(RuntimeError, "deu"):
check_ocr("deu+eng")
with self.assertRaises(ValueError):
check_ocr("--bad-language")
@unittest.skipUnless(shutil.which("tesseract") and shutil.which("pdftotext"), "Tesseract and Poppler required")
def test_ocr_keeps_receipt_canvas_blank_back_and_page_order_with_real_extractable_text(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
pages = []
for index, text in enumerate(["FEDEO Bon 12345", "", "Zweite Seite 24680"]):
page = root / f"page-{index}.png"
image = Image.new("RGB", (1240, 1754), (45, 45, 45) if index == 0 else "white")
draw = ImageDraw.Draw(image)
if index == 0:
draw.rectangle((260, 150, 1000, 1550), fill="white")
if text:
draw.text((300, 300), text, fill="black", font=ImageFont.load_default(size=44))
draw.text((300, 390), "Summe EUR 12,34", fill="black", font=ImageFont.load_default(size=36))
image.save(page)
pages.append(page)
output = root / "searchable.pdf"
result = create_document(pages, output, 150, ocr=True, background_cleanup=True)
self.assertEqual(result["pageCount"], 3)
with PdfParser.PdfParser(filename=str(output)) as pdf:
self.assertEqual(len(pdf.pages), 3)
for reference in pdf.pages:
box = pdf.read_indirect(reference)[b"MediaBox"]
self.assertAlmostEqual(box[2], 1240 * 72 / 150, delta=.1)
self.assertAlmostEqual(box[3], 1754 * 72 / 150, delta=.1)
text = subprocess.check_output(["pdftotext", str(output), "-"], text=True)
extracted = text.split("\f")
self.assertIn("12345", extracted[0])
self.assertEqual(extracted[1].strip(), "")
self.assertIn("24680", extracted[2])
self.assertTrue(all(page.exists() for page in pages))
def test_ocr_failure_never_publishes_a_partial_document_or_removes_raw_pages(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
page = root / "raw.png"
Image.new("RGB", (400, 600), "white").save(page)
output = root / "failed.pdf"
with patch("scan_document.check_ocr"), patch("scan_document.run_ocr_command", side_effect=RuntimeError("OCR failed")):
with self.assertRaisesRegex(RuntimeError, "OCR failed"):
create_document([page], output, 300, ocr=True)
self.assertFalse(output.exists())
self.assertFalse(output.with_name("failed.pdf.partial").exists())
self.assertTrue(page.exists())
self.assertEqual(list(root.glob("prepared-*")), [])
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,16 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": ["ES2022", "DOM"],
"types": ["node"],
"rootDir": "src",
"outDir": "dist",
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
},
"include": ["src/**/*.ts"]
}

7
backend/.dockerignore Normal file
View File

@@ -0,0 +1,7 @@
node_modules
dist
.git
.env
.env.*
!.env.example
*.log

6
backend/.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
node_modules
# Keep environment variables out of version control
.env
/src/generated/prisma
/dist/

18
backend/.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,18 @@
before_script:
- docker info
stages:
- build
build-backend:
stage: build
tags:
- shell
- docker-daemon
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
script:
- echo $IMAGE_TAG
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG

View File

@@ -0,0 +1,3 @@
{
"rules": []
}

33
backend/Dockerfile Normal file
View File

@@ -0,0 +1,33 @@
FROM node:22-bookworm-slim
WORKDIR /usr/src/app
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
poppler-utils \
tesseract-ocr \
tesseract-ocr-deu \
tesseract-ocr-eng \
&& rm -rf /var/lib/apt/lists/*
# Package-Dateien
COPY package*.json ./
# Dev + Prod Dependencies (für TS-Build nötig).
# Optionale native Linux-Pakete werden aus dem Lockfile installiert.
RUN npm ci --include=optional
# Restlicher Sourcecode
COPY . .
# TypeScript Build
ARG FEDEO_VERSION=0.0.0-dev
ARG FEDEO_REVISION=unknown
ENV FEDEO_VERSION=$FEDEO_VERSION
ENV FEDEO_REVISION=$FEDEO_REVISION
RUN npm run build && node --import tsx --test tests/*.test.ts
# Port freigeben
EXPOSE 3100
# Migrationen ausführen und App starten
CMD ["sh", "./docker-entrypoint.sh"]

32
backend/TODO.md Normal file
View File

@@ -0,0 +1,32 @@
# Projekt To-Do Liste
## ✅ Erledigt
- JWT-basierte Authentifizierung mit Cookie
- Prefix für Auth-Tabellen (`auth_users`, `auth_roles`, …)
- `/me` liefert User + Rechte (via `auth_get_user_permissions`)
- Basis-Seed für Standardrollen + Rechte eingespielt
- Auth Middleware im Frontend korrigiert (Login-Redirects)
- Nuxt API Plugin unterstützt JWT im Header
- Login-Seite an Nuxt UI Pro (v2) anpassen
- `usePermission()` Composable im Frontend vorbereitet
---
## 🔄 Offene Punkte
### Backend
- [ ] `/me` erweitern: Rollen + deren Rechte strukturiert zurückgeben (`{ role: "manager", permissions: [...] }`)
- [ ] Loading Flag im Auth-Flow berücksichtigen (damit `me` nicht doppelt feuert)
- [ ] Gemeinsames Schema für Entities (Backend stellt per Endpoint bereit)
- [ ] Soft Delete vereinheitlichen (`archived = true` statt DELETE)
- [ ] Swagger-Doku verbessern (Schemas, Beispiele)
### Frontend
- [ ] Loading Flag in Middleware/Store einbauen
- [ ] Einheitliches Laden des Schemas beim Start
- [ ] Pinia-Store für Auth/User/Tenant konsolidieren
- [ ] Composable `usePermission(key)` implementieren, um Rechte einfach im Template zu prüfen
- [ ] Entity-Seiten schrittweise auf API-Routen umstellen
- [ ] Page Guards für Routen einbauen (z. B. `/projects/create` nur bei `projects-create`)
---

33
backend/db/index.ts Normal file
View File

@@ -0,0 +1,33 @@
// src/db/index.ts
import { drizzle } from "drizzle-orm/node-postgres";
import { Pool } from "pg";
import * as schema from "./schema";
import {secrets} from "../src/utils/secrets";
console.log("[DB INIT] 1. Suche Connection String...");
const fallbackConnectionString = "postgres://postgres:wJw7aNpEBJdcxgoct6GXNpvY4Cn6ECqu@fedeo-db-001.vpn.internal:5432/fedeo"
// Checken woher die URL kommt
let connectionString = process.env.DATABASE_URL || secrets.DATABASE_URL || fallbackConnectionString;
if (process.env.DATABASE_URL) {
console.log("[DB INIT] -> Gefunden in process.env.DATABASE_URL");
} else if (secrets.DATABASE_URL) {
console.log("[DB INIT] -> Gefunden in secrets.DATABASE_URL");
} else if (connectionString) {
console.log("[DB INIT] -> Nutze Fallback aus dem Projekt");
} else {
console.error("[DB INIT] ❌ KEIN CONNECTION STRING GEFUNDEN! .env nicht geladen?");
}
export const pool = new Pool({
connectionString,
max: 10,
});
// TEST: Ist die DB wirklich da?
pool.query('SELECT NOW()')
.then(res => console.log(`[DB INIT] ✅ VERBINDUNG ERFOLGREICH! Zeit auf DB: ${res.rows[0].now}`))
.catch(err => console.error(`[DB INIT] ❌ VERBINDUNGSFEHLER:`, err.message));
export const db = drizzle(pool, { schema });

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
CREATE TABLE "time_events" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" bigint NOT NULL,
"user_id" uuid NOT NULL,
"actor_type" text NOT NULL,
"actor_user_id" uuid,
"event_time" timestamp with time zone NOT NULL,
"event_type" text NOT NULL,
"source" text NOT NULL,
"invalidates_event_id" uuid,
"metadata" jsonb,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "time_events_actor_user_check" CHECK (
(actor_type = 'system' AND actor_user_id IS NULL)
OR
(actor_type = 'user' AND actor_user_id IS NOT NULL)
)
);
--> statement-breakpoint
ALTER TABLE "bankstatements" DROP CONSTRAINT "bankstatements_incomingInvoice_incominginvoices_id_fk";
--> statement-breakpoint
ALTER TABLE "bankstatements" DROP CONSTRAINT "bankstatements_createdDocument_createddocuments_id_fk";
--> statement-breakpoint
ALTER TABLE "time_events" ADD CONSTRAINT "time_events_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "time_events" ADD CONSTRAINT "time_events_user_id_auth_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "time_events" ADD CONSTRAINT "time_events_actor_user_id_auth_users_id_fk" FOREIGN KEY ("actor_user_id") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "time_events" ADD CONSTRAINT "time_events_invalidates_event_id_time_events_id_fk" FOREIGN KEY ("invalidates_event_id") REFERENCES "public"."time_events"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
CREATE INDEX "idx_time_events_tenant_user_time" ON "time_events" USING btree ("tenant_id","user_id","event_time");--> statement-breakpoint
CREATE INDEX "idx_time_events_created_at" ON "time_events" USING btree ("created_at");--> statement-breakpoint
CREATE INDEX "idx_time_events_invalidates" ON "time_events" USING btree ("invalidates_event_id");--> statement-breakpoint
ALTER TABLE "bankstatements" DROP COLUMN "incomingInvoice";--> statement-breakpoint
ALTER TABLE "bankstatements" DROP COLUMN "createdDocument";

View File

@@ -0,0 +1,13 @@
ALTER TABLE "time_events" RENAME TO "staff_time_events";--> statement-breakpoint
ALTER TABLE "staff_time_events" DROP CONSTRAINT "time_events_tenant_id_tenants_id_fk";
--> statement-breakpoint
ALTER TABLE "staff_time_events" DROP CONSTRAINT "time_events_user_id_auth_users_id_fk";
--> statement-breakpoint
ALTER TABLE "staff_time_events" DROP CONSTRAINT "time_events_actor_user_id_auth_users_id_fk";
--> statement-breakpoint
ALTER TABLE "staff_time_events" DROP CONSTRAINT "time_events_invalidates_event_id_time_events_id_fk";
--> statement-breakpoint
ALTER TABLE "staff_time_events" ADD CONSTRAINT "staff_time_events_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "staff_time_events" ADD CONSTRAINT "staff_time_events_user_id_auth_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "staff_time_events" ADD CONSTRAINT "staff_time_events_actor_user_id_auth_users_id_fk" FOREIGN KEY ("actor_user_id") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "staff_time_events" ADD CONSTRAINT "staff_time_events_invalidates_event_id_staff_time_events_id_fk" FOREIGN KEY ("invalidates_event_id") REFERENCES "public"."staff_time_events"("id") ON DELETE no action ON UPDATE no action;

View File

@@ -0,0 +1,2 @@
-- No-op migration: Datei war im Journal referenziert, aber fehlte im Repository.
SELECT 1;

View File

@@ -0,0 +1,2 @@
-- No-op migration: Datei war im Journal referenziert, aber fehlte im Repository.
SELECT 1;

View File

@@ -0,0 +1,95 @@
CREATE TABLE "m2m_api_keys" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
"tenant_id" bigint NOT NULL,
"user_id" uuid NOT NULL,
"created_by" uuid,
"name" text NOT NULL,
"key_prefix" text NOT NULL,
"key_hash" text NOT NULL,
"active" boolean DEFAULT true NOT NULL,
"last_used_at" timestamp with time zone,
"expires_at" timestamp with time zone,
CONSTRAINT "m2m_api_keys_key_hash_unique" UNIQUE("key_hash")
);
--> statement-breakpoint
CREATE TABLE "serialtypes" (
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (sequence name "serialtypes_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1),
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"name" text NOT NULL,
"intervall" text,
"icon" text,
"tenant" bigint NOT NULL,
"archived" boolean DEFAULT false NOT NULL,
"updated_at" timestamp with time zone,
"updated_by" uuid
);
--> statement-breakpoint
CREATE TABLE "serial_executions" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant" bigint NOT NULL,
"execution_date" timestamp NOT NULL,
"status" text DEFAULT 'draft',
"created_by" text,
"created_at" timestamp DEFAULT now(),
"summary" text
);
--> statement-breakpoint
CREATE TABLE "public_links" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"token" text NOT NULL,
"tenant" integer NOT NULL,
"default_profile" uuid,
"is_protected" boolean DEFAULT false NOT NULL,
"pin_hash" text,
"config" jsonb DEFAULT '{}'::jsonb,
"name" text NOT NULL,
"description" text,
"active" boolean DEFAULT true NOT NULL,
"created_at" timestamp DEFAULT now(),
"updated_at" timestamp DEFAULT now(),
CONSTRAINT "public_links_token_unique" UNIQUE("token")
);
--> statement-breakpoint
CREATE TABLE "wiki_pages" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" bigint NOT NULL,
"parent_id" uuid,
"title" text NOT NULL,
"content" jsonb,
"is_folder" boolean DEFAULT false NOT NULL,
"sort_order" integer DEFAULT 0 NOT NULL,
"entity_type" text,
"entity_id" bigint,
"entity_uuid" uuid,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone,
"created_by" uuid,
"updated_by" uuid
);
--> statement-breakpoint
ALTER TABLE "projects" ALTER COLUMN "active_phase" SET DEFAULT 'Erstkontakt';--> statement-breakpoint
ALTER TABLE "createddocuments" ADD COLUMN "serialexecution" uuid;--> statement-breakpoint
ALTER TABLE "devices" ADD COLUMN "last_seen" timestamp with time zone;--> statement-breakpoint
ALTER TABLE "devices" ADD COLUMN "last_debug_info" jsonb;--> statement-breakpoint
ALTER TABLE "files" ADD COLUMN "size" bigint;--> statement-breakpoint
ALTER TABLE "staff_time_events" ADD COLUMN "related_event_id" uuid;--> statement-breakpoint
ALTER TABLE "m2m_api_keys" ADD CONSTRAINT "m2m_api_keys_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "m2m_api_keys" ADD CONSTRAINT "m2m_api_keys_user_id_auth_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."auth_users"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "m2m_api_keys" ADD CONSTRAINT "m2m_api_keys_created_by_auth_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."auth_users"("id") ON DELETE set null ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "staff_time_events" ADD CONSTRAINT "staff_time_events_related_event_id_staff_time_events_id_fk" FOREIGN KEY ("related_event_id") REFERENCES "public"."staff_time_events"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "serialtypes" ADD CONSTRAINT "serialtypes_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "serialtypes" ADD CONSTRAINT "serialtypes_updated_by_auth_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "serial_executions" ADD CONSTRAINT "serial_executions_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "public_links" ADD CONSTRAINT "public_links_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "public_links" ADD CONSTRAINT "public_links_default_profile_auth_profiles_id_fk" FOREIGN KEY ("default_profile") REFERENCES "public"."auth_profiles"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "wiki_pages" ADD CONSTRAINT "wiki_pages_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "wiki_pages" ADD CONSTRAINT "wiki_pages_parent_id_wiki_pages_id_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."wiki_pages"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "wiki_pages" ADD CONSTRAINT "wiki_pages_created_by_auth_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "wiki_pages" ADD CONSTRAINT "wiki_pages_updated_by_auth_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
CREATE INDEX "wiki_pages_tenant_idx" ON "wiki_pages" USING btree ("tenant_id");--> statement-breakpoint
CREATE INDEX "wiki_pages_parent_idx" ON "wiki_pages" USING btree ("parent_id");--> statement-breakpoint
CREATE INDEX "wiki_pages_entity_int_idx" ON "wiki_pages" USING btree ("tenant_id","entity_type","entity_id");--> statement-breakpoint
CREATE INDEX "wiki_pages_entity_uuid_idx" ON "wiki_pages" USING btree ("tenant_id","entity_type","entity_uuid");--> statement-breakpoint
ALTER TABLE "createddocuments" ADD CONSTRAINT "createddocuments_serialexecution_serial_executions_id_fk" FOREIGN KEY ("serialexecution") REFERENCES "public"."serial_executions"("id") ON DELETE no action ON UPDATE no action;

View File

@@ -0,0 +1 @@
ALTER TABLE "services" ADD COLUMN "priceUpdateLocked" boolean DEFAULT false NOT NULL;

View File

@@ -0,0 +1 @@
ALTER TABLE "customers" ADD COLUMN "customTaxType" text;

View File

@@ -0,0 +1,16 @@
CREATE TABLE "contracttypes" (
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (sequence name "contracttypes_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1),
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"tenant" bigint NOT NULL,
"name" text NOT NULL,
"description" text,
"paymentType" text,
"recurring" boolean DEFAULT false NOT NULL,
"archived" boolean DEFAULT false NOT NULL,
"updated_at" timestamp with time zone,
"updated_by" uuid
);
--> statement-breakpoint
ALTER TABLE "contracttypes" ADD CONSTRAINT "contracttypes_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "contracttypes" ADD CONSTRAINT "contracttypes_updated_by_auth_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;

View File

@@ -0,0 +1,3 @@
ALTER TABLE "contracts" ADD COLUMN "contracttype" bigint;
--> statement-breakpoint
ALTER TABLE "contracts" ADD CONSTRAINT "contracts_contracttype_contracttypes_id_fk" FOREIGN KEY ("contracttype") REFERENCES "public"."contracttypes"("id") ON DELETE no action ON UPDATE no action;

View File

@@ -0,0 +1,3 @@
ALTER TABLE "contracttypes" ADD COLUMN "billingInterval" text;
--> statement-breakpoint
ALTER TABLE "contracts" ADD COLUMN "billingInterval" text;

View File

@@ -0,0 +1,16 @@
CREATE TABLE "entitybankaccounts" (
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (sequence name "entitybankaccounts_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1),
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"tenant" bigint NOT NULL,
"iban_encrypted" jsonb NOT NULL,
"bic_encrypted" jsonb NOT NULL,
"bank_name_encrypted" jsonb NOT NULL,
"description" text,
"updated_at" timestamp with time zone,
"updated_by" uuid,
"archived" boolean DEFAULT false NOT NULL
);
--> statement-breakpoint
ALTER TABLE "entitybankaccounts" ADD CONSTRAINT "entitybankaccounts_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "entitybankaccounts" ADD CONSTRAINT "entitybankaccounts_updated_by_auth_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;

View File

@@ -0,0 +1,73 @@
CREATE TABLE "customerspaces" (
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (sequence name "customerspaces_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1),
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"name" text NOT NULL,
"type" text NOT NULL,
"tenant" bigint NOT NULL,
"customer" bigint NOT NULL,
"spaceNumber" text NOT NULL,
"parentSpace" bigint,
"infoData" jsonb DEFAULT '{"zip":"","city":"","streetNumber":""}'::jsonb NOT NULL,
"description" text,
"archived" boolean DEFAULT false NOT NULL,
"updated_at" timestamp with time zone,
"updated_by" uuid
);
--> statement-breakpoint
CREATE TABLE "customerinventoryitems" (
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (sequence name "customerinventoryitems_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1),
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"name" text NOT NULL,
"description" text,
"tenant" bigint NOT NULL,
"customer" bigint NOT NULL,
"customerspace" bigint,
"customerInventoryId" text NOT NULL,
"serialNumber" text,
"quantity" bigint DEFAULT 0 NOT NULL,
"manufacturer" text,
"manufacturerNumber" text,
"purchaseDate" date,
"purchasePrice" double precision DEFAULT 0,
"currentValue" double precision,
"product" bigint,
"archived" boolean DEFAULT false NOT NULL,
"updated_at" timestamp with time zone,
"updated_by" uuid
);
--> statement-breakpoint
ALTER TABLE "customerspaces" ADD CONSTRAINT "customerspaces_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "customerspaces" ADD CONSTRAINT "customerspaces_customer_customers_id_fk" FOREIGN KEY ("customer") REFERENCES "public"."customers"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "customerspaces" ADD CONSTRAINT "customerspaces_parentSpace_customerspaces_id_fk" FOREIGN KEY ("parentSpace") REFERENCES "public"."customerspaces"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "customerspaces" ADD CONSTRAINT "customerspaces_updated_by_auth_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "customerinventoryitems" ADD CONSTRAINT "customerinventoryitems_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "customerinventoryitems" ADD CONSTRAINT "customerinventoryitems_customer_customers_id_fk" FOREIGN KEY ("customer") REFERENCES "public"."customers"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "customerinventoryitems" ADD CONSTRAINT "customerinventoryitems_customerspace_customerspaces_id_fk" FOREIGN KEY ("customerspace") REFERENCES "public"."customerspaces"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "customerinventoryitems" ADD CONSTRAINT "customerinventoryitems_product_products_id_fk" FOREIGN KEY ("product") REFERENCES "public"."products"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "customerinventoryitems" ADD CONSTRAINT "customerinventoryitems_updated_by_auth_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
CREATE UNIQUE INDEX "customerinventoryitems_tenant_customerInventoryId_idx" ON "customerinventoryitems" USING btree ("tenant","customerInventoryId");
--> statement-breakpoint
ALTER TABLE "historyitems" ADD COLUMN "customerspace" bigint;
--> statement-breakpoint
ALTER TABLE "historyitems" ADD COLUMN "customerinventoryitem" bigint;
--> statement-breakpoint
ALTER TABLE "historyitems" ADD CONSTRAINT "historyitems_customerspace_customerspaces_id_fk" FOREIGN KEY ("customerspace") REFERENCES "public"."customerspaces"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "historyitems" ADD CONSTRAINT "historyitems_customerinventoryitem_customerinventoryitems_id_fk" FOREIGN KEY ("customerinventoryitem") REFERENCES "public"."customerinventoryitems"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "tenants" ALTER COLUMN "numberRanges" SET DEFAULT '{"vendors":{"prefix":"","suffix":"","nextNumber":10000},"customers":{"prefix":"","suffix":"","nextNumber":10000},"products":{"prefix":"AT-","suffix":"","nextNumber":1000},"quotes":{"prefix":"AN-","suffix":"","nextNumber":1000},"confirmationOrders":{"prefix":"AB-","suffix":"","nextNumber":1000},"invoices":{"prefix":"RE-","suffix":"","nextNumber":1000},"spaces":{"prefix":"LP-","suffix":"","nextNumber":1000},"customerspaces":{"prefix":"KLP-","suffix":"","nextNumber":1000},"inventoryitems":{"prefix":"IA-","suffix":"","nextNumber":1000},"customerinventoryitems":{"prefix":"KIA-","suffix":"","nextNumber":1000},"projects":{"prefix":"PRJ-","suffix":"","nextNumber":1000},"costcentres":{"prefix":"KST-","suffix":"","nextNumber":1000}}'::jsonb;
--> statement-breakpoint
UPDATE "tenants"
SET "numberRanges" = COALESCE("numberRanges", '{}'::jsonb) || jsonb_build_object(
'customerspaces', COALESCE("numberRanges"->'customerspaces', '{"prefix":"KLP-","suffix":"","nextNumber":1000}'::jsonb),
'customerinventoryitems', COALESCE("numberRanges"->'customerinventoryitems', '{"prefix":"KIA-","suffix":"","nextNumber":1000}'::jsonb)
);

View File

@@ -0,0 +1,3 @@
ALTER TABLE "customerinventoryitems" ADD COLUMN "vendor" bigint;
--> statement-breakpoint
ALTER TABLE "customerinventoryitems" ADD CONSTRAINT "customerinventoryitems_vendor_vendors_id_fk" FOREIGN KEY ("vendor") REFERENCES "public"."vendors"("id") ON DELETE no action ON UPDATE no action;

View File

@@ -0,0 +1,20 @@
CREATE TABLE "memberrelations" (
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (sequence name "memberrelations_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1),
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"tenant" bigint NOT NULL,
"type" text NOT NULL,
"billingInterval" text NOT NULL,
"billingAmount" double precision DEFAULT 0 NOT NULL,
"archived" boolean DEFAULT false NOT NULL,
"updated_at" timestamp with time zone,
"updated_by" uuid
);
--> statement-breakpoint
ALTER TABLE "customers" ADD COLUMN "memberrelation" bigint;
--> statement-breakpoint
ALTER TABLE "memberrelations" ADD CONSTRAINT "memberrelations_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "memberrelations" ADD CONSTRAINT "memberrelations_updated_by_auth_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "customers" ADD CONSTRAINT "customers_memberrelation_memberrelations_id_fk" FOREIGN KEY ("memberrelation") REFERENCES "public"."memberrelations"("id") ON DELETE no action ON UPDATE no action;

View File

@@ -0,0 +1,4 @@
ALTER TABLE "historyitems" ADD COLUMN "memberrelation" bigint;
--> statement-breakpoint
ALTER TABLE "historyitems" ADD CONSTRAINT "historyitems_memberrelation_memberrelations_id_fk" FOREIGN KEY ("memberrelation") REFERENCES "public"."memberrelations"("id") ON DELETE no action ON UPDATE no action;

View File

@@ -0,0 +1,33 @@
ALTER TABLE "customers" ADD COLUMN IF NOT EXISTS "memberrelation" bigint;
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1
FROM pg_constraint
WHERE conname = 'customers_memberrelation_memberrelations_id_fk'
) THEN
ALTER TABLE "customers"
ADD CONSTRAINT "customers_memberrelation_memberrelations_id_fk"
FOREIGN KEY ("memberrelation")
REFERENCES "public"."memberrelations"("id")
ON DELETE no action
ON UPDATE no action;
END IF;
END $$;
UPDATE "customers"
SET "memberrelation" = ("infoData"->>'memberrelation')::bigint
WHERE
"memberrelation" IS NULL
AND "type" = 'Mitglied'
AND jsonb_typeof(COALESCE("infoData", '{}'::jsonb)) = 'object'
AND COALESCE("infoData", '{}'::jsonb) ? 'memberrelation'
AND ("infoData"->>'memberrelation') ~ '^[0-9]+$';
UPDATE "customers"
SET "infoData" = COALESCE("infoData", '{}'::jsonb) - 'memberrelation'
WHERE
"type" = 'Mitglied'
AND jsonb_typeof(COALESCE("infoData", '{}'::jsonb)) = 'object'
AND COALESCE("infoData", '{}'::jsonb) ? 'memberrelation';

View File

@@ -0,0 +1 @@
-- Absichtlich leer: Die Objekte aus dieser generierten Migration existieren bereits in früheren Migrationen.

View File

@@ -0,0 +1,3 @@
ALTER TABLE "accounts" ADD COLUMN "accountChart" text DEFAULT 'skr03' NOT NULL;
--> statement-breakpoint
ALTER TABLE "tenants" ADD COLUMN "accountChart" text DEFAULT 'skr03' NOT NULL;

View File

@@ -0,0 +1,3 @@
ALTER TABLE "createddocuments"
ALTER COLUMN "customSurchargePercentage" TYPE double precision
USING "customSurchargePercentage"::double precision;

View File

@@ -0,0 +1 @@
ALTER TABLE "files" ADD COLUMN "extracted_text" text;

View File

@@ -0,0 +1,2 @@
ALTER TABLE "auth_users"
ADD COLUMN "is_admin" boolean NOT NULL DEFAULT false;

View File

@@ -0,0 +1,2 @@
ALTER TABLE "tasks"
ADD COLUMN "dependency_ids" jsonb NOT NULL DEFAULT '[]'::jsonb;

View File

@@ -0,0 +1,2 @@
ALTER TABLE "tenants"
ADD COLUMN "taxEvaluationPeriod" text DEFAULT 'monthly' NOT NULL;

View File

@@ -0,0 +1,37 @@
CREATE TABLE "branches" (
"id" bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"tenant" bigint NOT NULL,
"name" text NOT NULL,
"number" text,
"description" text,
"archived" boolean DEFAULT false NOT NULL,
"updated_at" timestamp with time zone,
"updated_by" uuid
);
--> statement-breakpoint
ALTER TABLE "branches" ADD CONSTRAINT "branches_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "branches" ADD CONSTRAINT "branches_updated_by_auth_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "costcentres" ADD COLUMN "branch" bigint;
--> statement-breakpoint
ALTER TABLE "costcentres" ADD CONSTRAINT "costcentres_branch_branches_id_fk" FOREIGN KEY ("branch") REFERENCES "public"."branches"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "auth_profiles" ADD COLUMN "branch_id" bigint;
--> statement-breakpoint
ALTER TABLE "auth_profiles" ADD CONSTRAINT "auth_profiles_branch_id_branches_id_fk" FOREIGN KEY ("branch_id") REFERENCES "public"."branches"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
CREATE TABLE "auth_profile_branches" (
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"profile_id" uuid NOT NULL,
"branch_id" bigint NOT NULL,
"created_by" uuid,
CONSTRAINT "auth_profile_branches_profile_id_branch_id_pk" PRIMARY KEY("profile_id","branch_id")
);
--> statement-breakpoint
ALTER TABLE "auth_profile_branches" ADD CONSTRAINT "auth_profile_branches_profile_id_auth_profiles_id_fk" FOREIGN KEY ("profile_id") REFERENCES "public"."auth_profiles"("id") ON DELETE cascade ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "auth_profile_branches" ADD CONSTRAINT "auth_profile_branches_branch_id_branches_id_fk" FOREIGN KEY ("branch_id") REFERENCES "public"."branches"("id") ON DELETE cascade ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "auth_profile_branches" ADD CONSTRAINT "auth_profile_branches_created_by_auth_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;

View File

@@ -0,0 +1,6 @@
ALTER TABLE "statementallocations"
ADD COLUMN "booking_mode" text DEFAULT 'expense' NOT NULL,
ADD COLUMN "depreciation_months" integer,
ADD COLUMN "depreciation_start_date" text,
ADD COLUMN "depreciation_label" text,
ADD COLUMN "depreciation_group" text;

View File

@@ -0,0 +1,3 @@
ALTER TABLE "statementallocations"
ADD COLUMN "depreciation_method" text,
ADD COLUMN "residual_value" double precision;

View File

@@ -0,0 +1,2 @@
ALTER TABLE "products"
ADD COLUMN "supplierLink" text;

View File

@@ -0,0 +1,31 @@
CREATE TABLE "teams" (
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (sequence name "teams_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1),
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"tenant" bigint NOT NULL,
"name" text NOT NULL,
"description" text,
"branch" bigint,
"archived" boolean DEFAULT false NOT NULL,
"updated_at" timestamp with time zone,
"updated_by" uuid
);
--> statement-breakpoint
CREATE TABLE "auth_profile_teams" (
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"profile_id" uuid NOT NULL,
"team_id" bigint NOT NULL,
"created_by" uuid,
CONSTRAINT "auth_profile_teams_profile_id_team_id_pk" PRIMARY KEY("profile_id","team_id")
);
--> statement-breakpoint
ALTER TABLE "teams" ADD CONSTRAINT "teams_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "teams" ADD CONSTRAINT "teams_branch_branches_id_fk" FOREIGN KEY ("branch") REFERENCES "public"."branches"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "teams" ADD CONSTRAINT "teams_updated_by_auth_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "auth_profile_teams" ADD CONSTRAINT "auth_profile_teams_profile_id_auth_profiles_id_fk" FOREIGN KEY ("profile_id") REFERENCES "public"."auth_profiles"("id") ON DELETE cascade ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "auth_profile_teams" ADD CONSTRAINT "auth_profile_teams_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "auth_profile_teams" ADD CONSTRAINT "auth_profile_teams_created_by_auth_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;

View File

@@ -0,0 +1 @@
ALTER TABLE "events" ADD COLUMN "quick" boolean DEFAULT false NOT NULL;

View File

@@ -0,0 +1,10 @@
ALTER TABLE "statementallocations" ALTER COLUMN "bs_id" DROP NOT NULL;
ALTER TABLE "statementallocations" ADD COLUMN "manual_booking_date" text;
ALTER TABLE "statementallocations" ADD COLUMN "contra_account" bigint;
ALTER TABLE "statementallocations" ADD COLUMN "contra_ownaccount" uuid;
ALTER TABLE "statementallocations" ADD COLUMN "contra_customer" bigint;
ALTER TABLE "statementallocations" ADD COLUMN "contra_vendor" bigint;
ALTER TABLE "statementallocations" ADD CONSTRAINT "statementallocations_contra_account_accounts_id_fk" FOREIGN KEY ("contra_account") REFERENCES "public"."accounts"("id") ON DELETE no action ON UPDATE no action;
ALTER TABLE "statementallocations" ADD CONSTRAINT "statementallocations_contra_ownaccount_ownaccounts_id_fk" FOREIGN KEY ("contra_ownaccount") REFERENCES "public"."ownaccounts"("id") ON DELETE no action ON UPDATE no action;
ALTER TABLE "statementallocations" ADD CONSTRAINT "statementallocations_contra_customer_customers_id_fk" FOREIGN KEY ("contra_customer") REFERENCES "public"."customers"("id") ON DELETE no action ON UPDATE no action;
ALTER TABLE "statementallocations" ADD CONSTRAINT "statementallocations_contra_vendor_vendors_id_fk" FOREIGN KEY ("contra_vendor") REFERENCES "public"."vendors"("id") ON DELETE no action ON UPDATE no action;

View File

@@ -0,0 +1 @@
ALTER TABLE "statementallocations" ADD COLUMN "datev_tax_key" text;

View File

@@ -0,0 +1 @@
ALTER TABLE "statementallocations" ADD COLUMN "manual_invoice_side" text;

View File

@@ -0,0 +1,2 @@
ALTER TABLE "costcentres" ADD COLUMN "parent_costcentre" uuid;
ALTER TABLE "costcentres" ADD CONSTRAINT "costcentres_parent_costcentre_costcentres_id_fk" FOREIGN KEY ("parent_costcentre") REFERENCES "public"."costcentres"("id") ON DELETE no action ON UPDATE no action;

View File

@@ -0,0 +1,8 @@
ALTER TABLE "events" ADD COLUMN "color" text;
UPDATE "events" AS e
SET "color" = COALESCE(t."calendarConfig"->'quickEntry'->>'color', '#2563eb')
FROM "tenants" AS t
WHERE e."tenant" = t."id"
AND e."quick" = true
AND e."color" IS NULL;

View File

@@ -0,0 +1,2 @@
ALTER TABLE "auth_profiles"
ADD COLUMN IF NOT EXISTS "availability_note" text;

View File

@@ -0,0 +1,3 @@
ALTER TABLE "historyitems" ADD COLUMN "contract" bigint;
--> statement-breakpoint
ALTER TABLE "historyitems" ADD CONSTRAINT "historyitems_contract_contracts_id_fk" FOREIGN KEY ("contract") REFERENCES "public"."contracts"("id") ON DELETE cascade ON UPDATE no action;

View File

@@ -0,0 +1 @@
ALTER TABLE "contracts" ADD COLUMN "allowedContracttypes" jsonb DEFAULT '[]'::jsonb NOT NULL;

View File

@@ -0,0 +1,53 @@
CREATE TABLE "outgoingsepamandates" (
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (sequence name "outgoingsepamandates_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1),
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"tenant" bigint NOT NULL,
"customer" bigint NOT NULL,
"bankaccount" bigint NOT NULL,
"reference" text NOT NULL,
"status" text DEFAULT 'Entwurf' NOT NULL,
"mandate_type" text DEFAULT 'CORE' NOT NULL,
"sequence_type" text DEFAULT 'RCUR' NOT NULL,
"signed_at" timestamp with time zone,
"valid_from" timestamp with time zone,
"valid_until" timestamp with time zone,
"default_mandate" boolean DEFAULT false NOT NULL,
"notes" text,
"archived" boolean DEFAULT false NOT NULL,
"updated_at" timestamp with time zone,
"updated_by" uuid
);
--> statement-breakpoint
ALTER TABLE "outgoingsepamandates" ADD CONSTRAINT "outgoingsepamandates_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "outgoingsepamandates" ADD CONSTRAINT "outgoingsepamandates_customer_customers_id_fk" FOREIGN KEY ("customer") REFERENCES "public"."customers"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "outgoingsepamandates" ADD CONSTRAINT "outgoingsepamandates_bankaccount_entitybankaccounts_id_fk" FOREIGN KEY ("bankaccount") REFERENCES "public"."entitybankaccounts"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "outgoingsepamandates" ADD CONSTRAINT "outgoingsepamandates_updated_by_auth_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "contracts" ADD COLUMN "outgoingsepamandate" bigint;
--> statement-breakpoint
ALTER TABLE "contracts" ADD CONSTRAINT "contracts_outgoingsepamandate_outgoingsepamandates_id_fk" FOREIGN KEY ("outgoingsepamandate") REFERENCES "public"."outgoingsepamandates"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "createddocuments" ADD COLUMN "outgoingsepamandate" bigint;
--> statement-breakpoint
ALTER TABLE "createddocuments" ADD CONSTRAINT "createddocuments_outgoingsepamandate_outgoingsepamandates_id_fk" FOREIGN KEY ("outgoingsepamandate") REFERENCES "public"."outgoingsepamandates"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "historyitems" ADD COLUMN "outgoingsepamandate" bigint;
--> statement-breakpoint
ALTER TABLE "historyitems" ADD CONSTRAINT "historyitems_outgoingsepamandate_outgoingsepamandates_id_fk" FOREIGN KEY ("outgoingsepamandate") REFERENCES "public"."outgoingsepamandates"("id") ON DELETE cascade ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "tenants" ALTER COLUMN "numberRanges" SET DEFAULT '{"vendors":{"prefix":"","suffix":"","nextNumber":10000},"customers":{"prefix":"","suffix":"","nextNumber":10000},"products":{"prefix":"AT-","suffix":"","nextNumber":1000},"quotes":{"prefix":"AN-","suffix":"","nextNumber":1000},"costEstimates":{"prefix":"KS-","suffix":"","nextNumber":1000},"confirmationOrders":{"prefix":"AB-","suffix":"","nextNumber":1000},"invoices":{"prefix":"RE-","suffix":"","nextNumber":1000},"deliveryNotes":{"prefix":"LS-","suffix":"","nextNumber":1000},"packingSlips":{"prefix":"PS-","suffix":"","nextNumber":1000},"spaces":{"prefix":"LP-","suffix":"","nextNumber":1000},"customerspaces":{"prefix":"KLP-","suffix":"","nextNumber":1000},"inventoryitems":{"prefix":"IA-","suffix":"","nextNumber":1000},"customerinventoryitems":{"prefix":"KIA-","suffix":"","nextNumber":1000},"projects":{"prefix":"PRJ-","suffix":"","nextNumber":1000},"costcentres":{"prefix":"KST-","suffix":"","nextNumber":1000},"outgoingsepamandates":{"prefix":"SEPA-","suffix":"","nextNumber":1000}}'::jsonb;
--> statement-breakpoint
UPDATE "tenants"
SET "numberRanges" = COALESCE("numberRanges", '{}'::jsonb) || jsonb_build_object(
'outgoingsepamandates',
COALESCE("numberRanges"->'outgoingsepamandates', '{"prefix":"SEPA-","suffix":"","nextNumber":1000}'::jsonb)
);
--> statement-breakpoint
UPDATE "tenants"
SET "features" = COALESCE("features", '{}'::jsonb) || jsonb_build_object(
'outgoingsepamandates',
COALESCE("features"->'outgoingsepamandates', 'true'::jsonb)
);

View File

@@ -0,0 +1,40 @@
CREATE TABLE "communication_rooms" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" bigint NOT NULL,
"key" text NOT NULL,
"name" text NOT NULL,
"topic" text,
"type" text DEFAULT 'room' NOT NULL,
"entity_type" text,
"entity_id" bigint,
"entity_uuid" uuid,
"archived" boolean DEFAULT false NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone,
"created_by" uuid,
"updated_by" uuid
);
ALTER TABLE "communication_rooms"
ADD CONSTRAINT "communication_rooms_tenant_id_tenants_id_fk"
FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id")
ON DELETE cascade ON UPDATE no action;
ALTER TABLE "communication_rooms"
ADD CONSTRAINT "communication_rooms_created_by_auth_users_id_fk"
FOREIGN KEY ("created_by") REFERENCES "public"."auth_users"("id")
ON DELETE no action ON UPDATE no action;
ALTER TABLE "communication_rooms"
ADD CONSTRAINT "communication_rooms_updated_by_auth_users_id_fk"
FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id")
ON DELETE no action ON UPDATE no action;
CREATE UNIQUE INDEX "communication_rooms_tenant_key_idx"
ON "communication_rooms" USING btree ("tenant_id", "key");
CREATE INDEX "communication_rooms_tenant_idx"
ON "communication_rooms" USING btree ("tenant_id");
CREATE INDEX "communication_rooms_entity_idx"
ON "communication_rooms" USING btree ("tenant_id", "entity_type", "entity_id", "entity_uuid");

View File

@@ -0,0 +1,5 @@
ALTER TABLE "events" ADD COLUMN "state" text DEFAULT 'Final' NOT NULL;
UPDATE "events"
SET "state" = 'Final'
WHERE "state" IS NULL;

View File

@@ -0,0 +1 @@
ALTER TABLE "events" ADD COLUMN "repeatInterval" text DEFAULT 'Keine Wiederholung' NOT NULL;

View File

@@ -0,0 +1,46 @@
CREATE TABLE "notification_push_subscriptions" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" bigint NOT NULL,
"user_id" uuid NOT NULL,
"endpoint" text NOT NULL,
"p256dh" text NOT NULL,
"auth" text NOT NULL,
"user_agent" text,
"device_label" text,
"meta" jsonb,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"last_seen_at" timestamp with time zone DEFAULT now() NOT NULL,
"disabled_at" timestamp with time zone,
CONSTRAINT "notification_push_subscriptions_endpoint_key" UNIQUE("endpoint")
);
ALTER TABLE "notification_push_subscriptions"
ADD CONSTRAINT "notification_push_subscriptions_tenant_id_tenants_id_fk"
FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id")
ON DELETE cascade ON UPDATE cascade;
ALTER TABLE "notification_push_subscriptions"
ADD CONSTRAINT "notification_push_subscriptions_user_id_auth_users_id_fk"
FOREIGN KEY ("user_id") REFERENCES "public"."auth_users"("id")
ON DELETE cascade ON UPDATE cascade;
INSERT INTO "notifications_event_types" (
"event_key",
"display_name",
"description",
"category",
"severity",
"allowed_channels"
) VALUES
('system.test_push', 'Test-Push', 'Testet Desktop-Benachrichtigungen für den angemeldeten Nutzer.', 'system', 'info', '["inapp", "push"]'::jsonb),
('communication.message.new', 'Neue Chatnachricht', 'Benachrichtigt über relevante neue Chatnachrichten.', 'communication', 'info', '["inapp", "push"]'::jsonb),
('communication.call.started', 'Besprechung gestartet', 'Benachrichtigt Raumteilnehmer über gestartete Audio- oder Videoanrufe.', 'communication', 'info', '["inapp", "push"]'::jsonb),
('communication.call.missed', 'Verpasster Anruf', 'Benachrichtigt über verpasste Besprechungen.', 'communication', 'warning', '["inapp", "push"]'::jsonb),
('communication.room.invited', 'Raumeinladung', 'Benachrichtigt über Einladungen in Kommunikationsräume.', 'communication', 'info', '["inapp", "push"]'::jsonb)
ON CONFLICT ("event_key") DO UPDATE SET
"display_name" = EXCLUDED."display_name",
"description" = EXCLUDED."description",
"category" = EXCLUDED."category",
"severity" = EXCLUDED."severity",
"allowed_channels" = EXCLUDED."allowed_channels",
"is_active" = true;

View File

@@ -0,0 +1,6 @@
ALTER TABLE "filetags" ADD COLUMN "isSystemUsed" boolean DEFAULT false NOT NULL;
UPDATE "filetags"
SET "isSystemUsed" = true
WHERE COALESCE("createddocumenttype", '') <> ''
OR COALESCE("incomingDocumentType", '') <> '';

View File

@@ -0,0 +1,2 @@
ALTER TABLE "auth_profiles"
ADD COLUMN "calendar_subscription_token" text;

View File

@@ -0,0 +1,2 @@
ALTER TABLE "auth_profiles"
ADD COLUMN IF NOT EXISTS "availability_note" text;

View File

@@ -0,0 +1,55 @@
CREATE TABLE IF NOT EXISTS "communication_rooms" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" bigint NOT NULL,
"key" text NOT NULL,
"name" text NOT NULL,
"topic" text,
"type" text DEFAULT 'room' NOT NULL,
"entity_type" text,
"entity_id" bigint,
"entity_uuid" uuid,
"archived" boolean DEFAULT false NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone,
"created_by" uuid,
"updated_by" uuid
);
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'communication_rooms_tenant_id_tenants_id_fk'
) THEN
ALTER TABLE "communication_rooms"
ADD CONSTRAINT "communication_rooms_tenant_id_tenants_id_fk"
FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id")
ON DELETE cascade ON UPDATE no action;
END IF;
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'communication_rooms_created_by_auth_users_id_fk'
) THEN
ALTER TABLE "communication_rooms"
ADD CONSTRAINT "communication_rooms_created_by_auth_users_id_fk"
FOREIGN KEY ("created_by") REFERENCES "public"."auth_users"("id")
ON DELETE no action ON UPDATE no action;
END IF;
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'communication_rooms_updated_by_auth_users_id_fk'
) THEN
ALTER TABLE "communication_rooms"
ADD CONSTRAINT "communication_rooms_updated_by_auth_users_id_fk"
FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id")
ON DELETE no action ON UPDATE no action;
END IF;
END $$;
CREATE UNIQUE INDEX IF NOT EXISTS "communication_rooms_tenant_key_idx"
ON "communication_rooms" USING btree ("tenant_id", "key");
CREATE INDEX IF NOT EXISTS "communication_rooms_tenant_idx"
ON "communication_rooms" USING btree ("tenant_id");
CREATE INDEX IF NOT EXISTS "communication_rooms_entity_idx"
ON "communication_rooms" USING btree ("tenant_id", "entity_type", "entity_id", "entity_uuid");

Some files were not shown because too many files have changed in this diff Show More