Commit Graph

14361 Commits

Author SHA1 Message Date
kolaente e4b0a487fc feat(date): accept a null modelValue in DatepickerWithRange 2026-06-08 13:54:09 +00:00
kolaente 8839c296a2 feat(date): show the matching preset name on the date-range button 2026-06-08 13:54:09 +00:00
kolaente 27bb80d11a feat(input): add quick-select shortcuts to the Datepicker 2026-06-08 13:54:09 +00:00
kolaente 43d0203358 feat(time-tracking): add the time-tracking store 2026-06-08 13:54:09 +00:00
kolaente 80c21e6f40 feat(time-tracking): add the v2 time-entry service 2026-06-08 13:54:09 +00:00
kolaente 565bf97294 refactor(config): add PRO_FEATURE constants for licensed features 2026-06-08 13:54:09 +00:00
kolaente 4a558fc57a fix(api/v2): expose v2-only token route groups via the routes endpoint 2026-06-08 13:54:09 +00:00
kolaente 74510bb00a fix(api/v2): group time-entries token routes under their own scope 2026-06-08 13:54:09 +00:00
kolaente 2858b8b827 test(time-tracking): cover the v2 time-entry routes 2026-06-08 13:54:09 +00:00
kolaente b8b376c53a test(time-tracking): cover the time_entries model 2026-06-08 13:54:09 +00:00
kolaente aef584c9fa feat(time-tracking): let clients subscribe to timer events 2026-06-08 13:54:09 +00:00
kolaente cf22f08974 feat(time-tracking): broadcast timer changes over websocket 2026-06-08 13:54:09 +00:00
kolaente e197b1912f feat(time-tracking): count tracked time entries per task 2026-06-08 13:54:09 +00:00
kolaente 0c5a0a99ec feat(time-tracking): dispatch time-entry events 2026-06-08 13:54:09 +00:00
kolaente 9454cd3ec5 feat(time-tracking): expose time entries on the v2 API 2026-06-08 13:54:09 +00:00
kolaente 4bd6a6c4f7 feat(time-tracking): filter time entries with the task DSL 2026-06-08 13:54:09 +00:00
kolaente 42795518e9 feat(time-tracking): add the time_entries model 2026-06-08 13:54:09 +00:00
kolaente 26c067cc38 refactor: extract preprocessFilterString from task filter parsing 2026-06-08 13:54:09 +00:00
kolaente 6387d8138a feat(time-tracking): add the time_entries table migration 2026-06-08 13:54:09 +00:00
renovate[bot] 8ff97a61de chore(deps): update dev-dependencies 2026-06-08 07:23:10 +00:00
Weijie Zhao 89ed627800 fix(auth): remove stale OIDC callback lock
The OpenID callback view used a localStorage "authenticating" flag to avoid submitting the same authorization code twice when the route was remounted during an auth layout swap.

That layout swap is now guarded by AUTH_ROUTE_NAMES, so openid.auth stays in the unauthenticated shell until redirectIfSaved() navigates away. The persistent flag can instead get stranded when the page is refreshed, closed, or interrupted during the callback, making future OIDC callbacks silently return before exchanging the code.

Remove the flag so each valid callback URL is processed normally while keeping the existing state validation and TOTP retry handling.
2026-06-08 07:22:54 +00:00
kolaente c2e1b078ce feat(api/v2): add project team shares CRUD on /api/v2 2026-06-07 15:33:20 +00:00
kolaente 627cd0a6f4 docs(api/v2): tag project team share fields for the v2 schema 2026-06-07 15:33:20 +00:00
Frederick [Bot] a2be36b5fe [skip ci] Updated swagger docs 2026-06-07 11:36:48 +00:00
kolaente c2d1e48c8c feat(api/v2): add team members (add/remove/admin-toggle) on /api/v2
The admin-toggle handler delegates to handler.DoUpdate — the same pipeline
v1's UpdateWeb wraps — instead of re-implementing the session/permission/commit
orchestration. TeamMember.Update now carries the persisted row back onto the
receiver so both v1 and v2 responses include id/created.
2026-06-07 10:48:23 +00:00
kolaente ef256273e0 docs(api/v2): annotate TeamMember fields for the v2 schema 2026-06-07 10:48:23 +00:00
kolaente ed4ae0cd43 feat(api/v2): add saved filter CRUD on /api/v2 2026-06-07 10:40:20 +00:00
kolaente a52ee1593a docs(api/v2): tag SavedFilter fields for the v2 schema 2026-06-07 10:40:20 +00:00
kolaente 9cddc137c5 feat(api/v2): add project user shares CRUD on /api/v2 2026-06-07 10:37:59 +00:00
kolaente 2c0608e47b docs(api/v2): tag project user share fields for the v2 schema 2026-06-07 10:37:59 +00:00
kolaente 7158334699 fix(api/v2): return 200 from notifications mark-all (creates nothing) 2026-06-07 10:05:24 +00:00
kolaente 604e5850bc docs: trim wordy comments in v2 notifications 2026-06-07 10:05:24 +00:00
kolaente 1ca5367f27 feat(api/v2): add notifications list/mark-read + mark-all on /api/v2
Ports the v1 DatabaseNotifications routes to the Huma /api/v2 API:
- GET /notifications lists the caller's own notifications (paginated)
- PUT /notifications/{notificationid} marks one (un-)read
- POST /notifications is a custom action marking all as read; the
  link-share guard, session and commit live in the handler since there
  is no CRUDable Do* for a bulk mark.

Adds fixture rows and a webtest matrix mirroring the v1 model behaviour
(own-only visibility, mark-(un)read, link-share refusal on every route).
2026-06-07 10:05:24 +00:00
kolaente 05c9c07e19 docs(api/v2): add doc/readOnly tags to notification model fields 2026-06-07 10:05:24 +00:00
kolaente fb4bca34dd docs: trim wordy comments to load-bearing whys 2026-06-07 09:57:51 +00:00
kolaente 1b47932916 feat(api/v2): add subscribe/unsubscribe on /api/v2
Port the Subscription resource from /api/v1 to the Huma-backed /api/v2:
POST /subscriptions/{entity}/{entityID} subscribes, DELETE unsubscribes.

The {entity} discriminator is bound as a string path param with an
enum:"project,task" tag; the model's CanCreate/CanDelete derive the numeric
EntityType from it and reject unknown kinds. Permissions and the
already-subscribed/forbidden checks come from the shared model via DoCreate/
DoDelete, identical to v1's generic handler. Mark the model's server-controlled
fields readOnly and add doc tags for the v2 schema.
2026-06-07 09:57:51 +00:00
kolaente 67bc3ff4f1 test(api/v2): cover central validation (422, invalid_fields, full-body webhook updates) 2026-06-06 21:09:56 +00:00
kolaente 24188480c4 feat(api/v2): return 422 with invalid_fields for validation errors 2026-06-06 21:09:56 +00:00
kolaente 45e05a5d27 feat(api/v2): enforce validation centrally in the Register wrapper 2026-06-06 21:09:56 +00:00
kolaente 5855ccc1d4 docs(webhooks): version-qualify the events endpoint link in the events field doc
In the v2 OpenAPI context a bare /webhooks/events reads as /api/v2/webhooks/events,
which does not exist — the events listing endpoint lives only on /api/v1. Point the
doc string at the absolute v1 path so v2 clients are not misled.
2026-06-06 19:50:41 +00:00
kolaente aac0322975 refactor(webhooks): mask write-only credentials in the model so create/update never echo them
Webhook.ReadAll already cleared the secret and basic-auth from responses,
but Create and Update did not, so the v2 handler patched the gap with a
maskWebhookCredentials helper. Centralize the masking in the model via a
maskCredentials helper called after every DB write (ReadAll, Create,
Update) and drop the v2 handler helper.

The credentials are client-provided, not server-generated: the DB row
keeps them and outgoing deliveries reload + HMAC-sign from the DB copy,
so clearing the returned in-memory struct is correct write-only handling.

Webhook is a shared model, so v1's create/update responses also stop
echoing the submitted secret/auth — intended, and approved by the
maintainer.
2026-06-06 19:50:41 +00:00
kolaente 98741d8171 test(api/v2): webhook CRUD permission matrix and config gate
Port the v1 webhook webtest to /api/v2 and extend it to the full
permission gradient the model enforces: list needs read access while
create/update/delete need write (Project.CanWrite), exercised across an
owned project and read/write/admin shares plus a no-access project. Also
assert credential masking, events-only updates, the 412 validation path,
and that the routes 404 when webhooks.enabled is false.

Add fixture webhooks 2-5 in projects 9/10/11/2 to back the matrix; they
do not collide with the e2e tests, which scope to project 1.
2026-06-06 19:50:41 +00:00
kolaente cf1f7c3309 feat(api/v2): add project webhooks CRUD on /api/v2
Port the project-webhook routes under /projects/{project}/webhooks to
the Huma /api/v2: list, create, update (events only), delete. There is
no ReadOne — webhooks carry secrets — so no max_permission and no
AutoPatch PATCH; update is PUT only, mirroring v1.

The resource self-registers and is gated by the webhooks.enabled config
flag inside the registrar (RegisterAll runs after config loads). The
write-only secret and basic-auth credentials are cleared from
create/update responses, matching how ReadAll masks them.
2026-06-06 19:50:41 +00:00
kolaente 3647551a79 docs(api/v2): tag Webhook fields for the v2 schema
Add doc tags to every exposed Webhook field, mark the server-controlled
ones (id, project_id, user_id, created_by, created, updated) readOnly,
and mark the secret and basic-auth credentials writeOnly. All three tags
are ignored by swaggo/XORM/govalidator, so v1 is unaffected.
2026-06-06 19:50:41 +00:00
kolaente d76c009808 fix(api/v2): map ValidationHTTPError to its HTTP status
translateDomainError only recognized web.HTTPErrorProcessor, so a
ValidationHTTPError from InvalidFieldError (e.g. an unknown webhook
event) leaked as a 500 instead of the 412 v1 returns. It carries the
status via GetHTTPCode() but cannot implement HTTPErrorProcessor because
the embedded web.HTTPError field shadows the method name. Add a
GetHTTPCode/GetCode branch so v2 surfaces the right status and preserves
the v1 numeric code on the body.
2026-06-06 19:50:41 +00:00
kolaente 43bbeed1c8 feat(api/v2): add task assignees (create/list/delete) on /api/v2
Port the v1 /tasks/{projecttask}/assignees routes to the Huma-backed
/api/v2. The resource self-registers (RegisterTaskAssigneeRoutes) and
reuses the model's Can* methods via the generic Do* handlers:

- POST /tasks/{projecttask}/assignees  → assign a user (body: user_id)
- GET  /tasks/{projecttask}/assignees  → list assignees (as users)
- DELETE /tasks/{projecttask}/assignees/{user} → un-assign

The list element type is []*user.User (assignees are returned as the
assigned users), which differs from the create body (a TaskAssginee
carrying user_id); the list handler type-asserts to []*user.User.
create/delete require write access to the task's project, list requires
read — enforced at the model level.

The webtest re-proves the full v1 permission matrix on the v2 surface
(read-only shares forbidden, write/admin allowed for create and delete;
already-assigned, no-project-access, missing-user, and missing-task
error codes) so v1's routes can be removed later.
2026-06-06 19:06:12 +00:00
kolaente f90868c595 docs(models): tag TaskAssignee fields for the v2 schema
Add doc: tags so Huma can describe user_id and created in the /api/v2
OpenAPI spec (it can't read Go comments), mark the server-set created
field readOnly, and give it an explicit json:"created" tag so it
serializes in snake_case like the rest of the v2 surface.
2026-06-06 19:06:12 +00:00
renovate[bot] 43d6e14289 chore(deps): update dev-dependencies 2026-06-06 19:05:39 +00:00
Claude a35518a099 docs: redirect translation requests to translation guide 2026-06-06 21:05:21 +02:00
renovate[bot] 8e09b69fb3 chore(deps): update dev-dependencies to v26.14.0 2026-06-06 11:18:01 +00:00