Commit 26c04d8
feat: add compliance timeline to overview (feature flagged)
* feat(db): add timeline models and enums for compliance timeline feature
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(api): add default timeline template definitions as code constants
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(api): add timeline date recalculation helper with tests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(api): add timelines service with CRUD, activation, pause/resume, phase completion
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(api): split timelines service into focused modules under 300 lines each
Extract lifecycle, phase editing, template management, and template resolution
into separate files to comply with the max 300 lines per file rule.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(api): add timeline DTOs, controllers, module registration, and Swagger cleanup
- DTOs: activate-timeline, update-phase, create-template, create-phase-template,
update-template, update-phase-template with class-validator decorators
- Customer controller: GET /timelines, GET /timelines/:id,
POST /timelines/:id/phases/:phaseId/ready with Slack webhook notification
- Admin template controller: full CRUD for timeline templates and their phases
- Admin org timelines controller: activate, pause, resume, phase CRUD, complete
- TimelinesModule registered in AppModule with all services and controllers
- Added @ApiExcludeController() to all 8 existing admin controllers
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(api): auto-create timeline on framework add and auto-complete phases on 100% tasks
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(app): add SWR hooks for timelines and admin timeline management
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(app): add reusable TimelinePhaseBar component
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: add generated prisma to gitignore and add completedBy include to findOne
* feat(app): add TimelineOverview component to Overview page
Add a compliance timeline section above the existing dashboard grid,
showing stacked timeline cards with phase bars, status badges, and
date summaries. Also updates the Timeline hook types to match the
actual API response (DRAFT/ACTIVE/PAUSED/COMPLETED statuses).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(app): add expanded timeline view to framework detail page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(app): add admin timeline template management page
Add a new admin page for managing timeline templates with CRUD operations.
Includes a template list with phase bar previews and a sheet editor for
creating/editing templates and their phases. Added sidebar navigation link.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(app): add Timeline tab to admin org detail page
Add a Timeline tab to the admin organization detail view showing all
timelines for an org. Includes status badges, phase tables, and action
buttons for activating (with date picker), pausing, resuming, and
editing individual phases via a sheet editor.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): auto-create timelines for existing framework instances on first load
* fix(api): fix type error in date helper tests
* feat(api): smart timeline backfill using trust status, scores, and task completion data
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(app): use design system tokens, remove outer card, add next cycle date
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(app): improve phase bar with progress indicator and add timeline summary
* fix(api): use 'Attestation' instead of 'Certification' for HIPAA and GDPR
* feat: separate SOC 2 Type 1 and Type 2 timelines, add date markers to phase bar
* fix: replace em dashes with hyphens in template names
* fix(api): wrap admin timeline endpoints in { data, count } response format
* fix(app): use correct timeline status values (DRAFT/ACTIVE/PAUSED/COMPLETED) in admin components
* fix(app): fix missing closing brace in TimelineCard
* fix(app): replace table layout with stacked phase cards in admin timeline view
* feat(app): add tabs to Overview page with Timeline tab and compact teaser
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(app): simplify timeline teaser to clean single-line banner without phase bar
* fix(app): remove timeline teaser from Overview tab
* fix(app): remove redundant header and summary from Timeline tab
* fix(app): use defaultDurationWeeks for template phase duration (fixes NaN)
* fix: recalculate end date and downstream phases when duration or start date changes
* feat(api): auto-complete timeline phases immediately when tasks are marked done
* feat: add phase grouping with groupLabel for SOC 2 Type 2 sub-phases
* feat(admin): add delete, reset, and recreate timeline actions with confirmation dialogs
* fix(app): close confirmation dialogs immediately on confirm
* fix(api): recreate also deletes DB templates so code defaults are re-seeded
* fix(api): force-refresh templates from code defaults during recreate
* fix(app): add bracket lines connecting group label to phase edges
* fix(app): render grouped phases as cohesive blocks with no internal gaps
* fix(app): show one start/end date per group instead of per sub-phase
* feat: add AUTO_POLICIES and AUTO_PEOPLE completion types for independent sub-phase tracking
* fix(api): use getOverviewScores for AUTO_POLICIES and AUTO_PEOPLE checks
* fix(api): use correct property names from scores (total/published)
* fix(app): wrap phase groups to new rows on small screens
* fix(app): vertical phase stack on mobile, horizontal bar on lg+ screens
* fix(app): keep grouped phases in one row on mobile, only ungrouped phases stack
* fix(app): treat ungrouped phases as individual groups so each gets its own row on mobile
* fix(app): show group labels and dates per row on mobile phase bar
* fix(app): replace mobile phase bars with clean vertical step list
* fix(app): compact horizontal bars on mobile without per-phase dates
* fix(app): remove checkmarks from completed phase bars
* fix(app): add diagonal stripe pattern to unfilled portion of active phase
* fix(app): use primary color for stripe pattern on active phase
* fix(app): use oklch color-mix for stripe pattern instead of hsl wrapper
* fix(app): reduce stripe opacity to 10% for subtler effect
* fix(app): reduce gap between phases from 3px to 1px
* fix(api): rename SOC 2 Type 2 - Year 1 to SOC 2 Type 2
* fix(app): remove redundant Started/Est. completion text from timeline cards
* feat: live completion percentages for AUTO_* phases, revert if metric drops below 100%
* fix(api): rename SOC 2 sub-phases to Policies, Evidence, People
* feat(app): show live completion % and fill for all AUTO_* sub-phases independently
* feat(app): show avg completion % on group label, single cohesive fill for grouped phases
* fix(app): show individual sub-phase percentages inside grouped bar
* fix(app): add pulsing progress marker to grouped phase bar
* feat(app): add dedicated full-page timeline template editor
Replace the drawer-based template editor with a dedicated page at
[orgId]/admin/timeline-templates/[templateId]. The new editor includes
metadata form, live phase bar preview, individual phase cards with
save/delete/reorder, and group label support with color indicators.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(app): framework dropdown in template creation and editing
* feat(api): centralized Slack notifications for phase completion, timeline completion, and ready-for-review
* fix(api): assign transaction result to txResult variable
* fix(api): use template name in Slack notifications to distinguish SOC 2 Type 1 vs Type 2
* fix(api): use Slack Block Kit for cleaner notification formatting
* feat(api): add clickable org link to Slack notifications with admin timeline URL
* fix(api): show org ID in Slack notification messages
* fix(app): only show stripes on IN_PROGRESS phases, plain muted for PENDING
* fix(api): only advance next phase to IN_PROGRESS when all prior phases are completed
* fix(app): show framework name instead of ID in template editor dropdown
* feat(app): group sub-phases under parent card in template editor
Phases that share a groupLabel are now nested inside a parent group
card with an editable label, total duration display, and "Add Sub-phase"
button. Sub-phases render as compact inline rows instead of full cards.
Ungrouped phases retain the existing full PhaseCard rendering.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(api): add Auditor Review + Draft Report phases to SOC 2 templates
* fix(app): phase numbering counts groups as 1, label below Phase N, add wk suffix to duration
* fix(app): use DS Text component for weeks label instead of custom span
* fix(app): add column labels (Name, Duration, Completion) above sub-phase rows
* feat(app): add confirmation dialogs to all delete actions in template editor
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): add groupLabel to phase template DTOs and service
* fix(api): remove AdminAuditLogInterceptor from template controller (no org context)
* fix(api): pass groupLabel from DTO to service in addPhase and updatePhase
* feat(api): add timeline auto-completion hooks to policies, members, tasks, and evidence services
Wire up checkAutoCompletePhases fire-and-forget calls in all services
that can affect compliance progress metrics, enabling automatic phase
completion/reversion when tasks, policies, people, or evidence change.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(api): add Preparing for Audit group (Policies, Evidence, People) to SOC 2 Type 1
* fix(api): auto-complete phases at 100% on page load, not just on events
* fix(app): group phase cards visually in admin timeline, show template name as title
* fix(api): use actual completion date as anchor for downstream phase recalculation
* chore(db): add migration for AUTO_POLICIES and AUTO_PEOPLE completion types
* feat: add Start Next Cycle action for completed timelines (admin only)
* fix(app): use render prop on AlertDialogTrigger to avoid nested buttons
* fix(app): destructure onStartNextCycle from TimelineActions props
* feat(app): group timeline cycles by framework with stacked card effect for past cycles
* fix(app): fix stacked card effect to show behind the main card
* fix(app): stacked card effect as thin strips peeking below main card
* fix(app): simple lip button below card for showing previous cycles
* fix(app): remove bottom border radius from card when previous cycles lip is attached
* fix(app): subtle muted background on previous cycles lip
* fix(app): reduce lip padding and font size for sleeker look
* refactor(app): migrate TimelineOverview to DS components (Card, Badge, Text, Stack)
* fix(app): improve timeline card padding, title size, and spacing
* fix(app): remove bg from previous cycles lip, only show on hover
* fix(app): remove lip, show cycle badge (Year 2) when multiple cycles exist
* fix(app): show Year badge on all timelines, computed from cycle count not internal ID
* fix(api): always use now() for completedAt and endDate when auto-completing phases
* fix(api): pin phase dates on early completion so recalculation doesn't overwrite them
* fix(api): use min(endDate, now) for completedAt in backfill to avoid future dates
* chore: update OpenAPI spec with timeline endpoints
* feat(timelines): add track-based SOC2 timeline model
* feat(findings): integrate timelines module and add AUTO_FINDINGS phase completion logic
* chore: ignore .worktrees directory
* feat(flags): add per-org PostHog feature flag admin toggle
Gates features behind PostHog flags evaluated per organization via group
targeting. Platform admins can list/toggle flags for a specific org from
the admin panel; end users pick up changes on route navigation.
- register org as PostHog group via OrganizationIdentifier in org layout
- useFeatureFlag hook (posthog-js/react based, auto-reactive)
- reload flags on route change so toggles propagate without full refresh
- admin endpoints list + patch flags for a given org (groupIdentify)
- Feature Flags tab in admin org panel with search + toggle
- gate Timeline tab in Overview behind is-timeline-enabled
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: timeline cleanup — Card DS fix, dedup import, timeline migration
- TimelineOverview uses DS Card title/headerAction props (no className)
- remove duplicate ApiExcludeController import
- add timeline prisma migration
- regenerate openapi.json
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(timeline,flags): address AI review feedback
API:
- reset timeline status to ACTIVE when reopening regressed phases so a
COMPLETED timeline never holds an IN_PROGRESS phase (fix data corruption)
- fire-and-forget createTimelinesForFrameworks so timeline creation errors
don't mask successful framework creation
- log errors in checkAutoCompletePhases .catch() in tasks/people/policies
services instead of swallowing silently
- apply AdminAuditLogInterceptor to feature flag admin controller so
PATCH toggles get audit-logged
- drop unused AdminAuditLogInterceptor import from admin-timeline-templates
controller (no orgId in path, interceptor would no-op)
- cache PostHog "not configured" state so warning logs once, not per request
- read Slack webhook URL + APP_URL at call time instead of module load time
so env var loading order doesn't silently disable notifications
App:
- surface SWR error state in FeatureFlagsTab so failed fetches don't render
as an empty "no flags found" panel
- check .error on api.delete / api.patch / api.post in template-actions so
partial saves throw instead of silently succeeding
- non-mutating sort of template.phases in TemplateEditorPage to avoid
corrupting SWR cache
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(timeline): address remaining AI review P2 feedback
API:
- extract COMPLETION_TYPES to shared timeline-constants, narrow DTO
completionType from string to CompletionType union
- trigger checkAutoCompletePhases on both done and not_relevant task
statuses (AUTO_TASKS counts both as finished)
- drop unnecessary checkAutoCompletePhases after task creation — a todo
task can't advance any AUTO phase
App:
- extract COMPLETION_OPTIONS constant to timeline-templates/constants
and share across PhaseRow, TemplateEditor, template-actions
- remove orderIndex from form state (controlled/uncontrolled hybrid);
compute from array position at submit time in template-actions
- convert TemplateMetadataForm's framework fetch from raw useEffect to
SWR with proper error handling
- delete duplicate admin layout under timeline-templates (parent admin
layout already guards the route)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(timelines): make findAllForOrganization pure-read
Previously GET /timelines mutated state (completed phases, reverted
regressed phases, updated timeline status). That violates HTTP semantics
and races under concurrent reads.
- extract the sync loop into TimelinesService.reconcileAutoPhasesForOrganization
(handles both advancement and regression, replaces the inline logic)
- findAllForOrganization is now a pure read: ensureTimelinesExist (idempotent
backfill) + fetch + in-memory enrichment with live completion percentages
- call reconcileAutoPhasesForOrganization from checkAutoCompletePhases so
every existing event hook (task/policy/people/findings mutations) drives
both advancement and regression — no stale state left for reads to repair
- recreateAllForOrganization explicitly reconciles before returning so
freshly-recreated timelines are synced against current metrics
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(timelines): always reconcile after checkAutoCompletePhases
The reconcile call sat after an early return for phases.length === 0,
which skipped it in the exact case it mattered: when all AUTO phases are
already COMPLETED and a metric drops (regression). Wrap the advancement
in a try/finally so reconciliation fires unconditionally on every event
hook — extract advancement into runPhaseAdvancement for readability.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(db): reorder timeline migrations to apply after main's latest
Three of the branch's timeline migrations were dated 2026-04-07/08, which
is before main's 20260410120000_add_finding_scope. On merge, Prisma would
apply them out-of-order relative to what staging/prod already have.
Rename them to 20260410130000-20260410130002 so they sit right after main's
latest migration while preserving internal dependency order (timeline
models → phase group label → auto policies/people completion types →
rest of timeline migrations).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: address cubic P1/P2 review feedback batch
API:
- remove unused UseInterceptors import from admin-timeline-templates
- add @Transform trim to UnlockTimelineDto so whitespace-only reason fails
@isnotempty validation
- log errors (this.logger.warn) on checkAutoCompletePhases .catch() in
people-invite and evidence-forms services (matches pattern elsewhere)
- replace unreachable ECONNREFUSED check in dynamic-manifest-loader with
the correct Prisma error code P1001
- forbidNonWhitelisted on FF admin controller's ValidationPipe so bogus
body keys return 400 instead of silently stripping
- @ISINT (not @IsNumber) on cycleNumber so 1.5 etc. is rejected
- wrap posthog groupIdentify + flush in try/catch in FF service — network
failures now surface as meaningful BadRequestException + log instead of
raw 500
- check response.ok in Slack helper so non-200s are logged
- return sendSlack promise from notify* helpers instead of floating it
- drop getScores' checkAutoCompletePhases call — mutation event hooks
already drive both advancement and regression; the dashboard read
shouldn't trigger heavy writes on every load
App:
- TemplateMetadataForm: reset(values) after save so isDirty flips back,
wrap setSaving in try/finally
- TemplateEditorPage: render distinct error state when the SWR fetch fails
instead of falling through to "Template not found"
- TimelineActivateForm: validate date before ISO conversion and wrap body
in try/finally so a bad date can't leave the button stuck in loading
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: address new cubic P1/P2 review batch
P1:
- template-actions: upsert phases first, then delete removed ones. Reverse
order meant a mid-save failure could drop phases before their replacements
were successfully written.
P2:
- tasks.service: trigger checkAutoCompletePhases on ANY status change
(bulk and single update). Limiting it to done/not_relevant missed
regressions when a finished task is reopened.
- findings.service: same — run reconciliation on every finding status
transition, not only when moving to closed.
- admin-feature-flags.service: paginate the PostHog feature_flags REST
response (follow `next` cursor) so orgs with >200 flags don't silently
drop the tail.
- admin-feature-flags.service: treat any non-empty string variant returned
by getAllFlags as enabled (multivariate flags report variant name, not
boolean true), not just strict `=== true`.
- DTOs: use @ISINT instead of @IsNumber for cycleNumber, orderIndex,
durationWeeks, defaultDurationWeeks — rejects fractional values at the
boundary instead of failing later at the DB Int column.
- timelines-phases.service: wire data.endDate and data.datesPinned
through the update. Previously the DTO advertised them but the service
silently ignored both.
- admin-org-timelines.controller: pass datesPinned from DTO to service.
- TimelineActivateForm: parse date input as local midnight (match
YYYY-MM-DD, construct Date with local components) so a negative-UTC-offset
user's chosen day isn't shifted by ISO serialization.
- FeatureFlagsTab: disable all flag switches while any PATCH is in flight
so a late rollback from a failed request can't overwrite a newer
successful toggle.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: address new cubic P1/P2 batch after main merge
P1:
- timelines-phases.service: if caller sets an explicit start/end date,
force datesPinned=true regardless of what the DTO says — storing a
specific date with datesPinned=false would let the downstream date
recalculator silently overwrite it
- template-actions.createNewTemplate: wrap the phase-creation loop in
try/catch and delete the orphan template on failure, so a failed phase
POST can't leave a template with zero phases in the framework's list
- timelines.service.ensureTimelinesExist: always call backfillTimeline
(which is idempotent per-track) instead of short-circuiting when any
timeline already exists. Repairs partial state from a half-succeeded
createTimelinesForFrameworks call (e.g. SOC 2 with only Type 1 created)
P2:
- markReadyForReview: return idempotently (alreadyReady=true) when the
phase is already marked, and only fire the Slack ping on the first
transition. Double-clicks / retries no longer spam the CX channel.
- timelines-slack.helper: use the same base-URL fallback chain the other
notifiers use (NEXT_PUBLIC_APP_URL → BETTER_AUTH_URL → APP_URL), and
escape user-supplied text before interpolating into Slack mrkdwn so org
names with `<`, `>`, `&`, `|` can't break link syntax.
- posthog.service: prefer POSTHOG_API_KEY over NEXT_PUBLIC_POSTHOG_KEY so
backend config can't be shadowed by frontend env values.
- tasks.service.createTask: re-run checkAutoCompletePhases after create —
a new todo task reduces AUTO_TASKS completion % and can regress a
previously COMPLETED phase.
- policies.service.spec: register a TimelinesService stub so the test
module compiles after the service gained that dependency.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: address new cubic P1/P2 batch
P1:
- admin-feature-flags.service: validate the PostHog pagination \`next\` URL
against the configured host before following it. A compromised or
malicious PostHog response could otherwise redirect pagination to an
attacker-controlled host and leak the Authorization header (personal
API key) via SSRF.
- findings.service: wire checkAutoCompletePhases into create() and
delete() too. Previously only update() triggered reconciliation, so
creating a new open finding or deleting the last open one could leave
AUTO_FINDINGS phases out of sync with the actual ratio.
P2:
- frameworks-timeline.helper.createTimelinesForFrameworks: try/catch per
track instead of wrapping the whole loop. A soc2_type1 failure no
longer silently skips soc2_type2 — each track is attempted
independently and logged on its own.
- timelines-date.helper: defensively copy Date objects on assignment so
the caller's timelineStartDate (and the pinned start/end dates of
input phases) can't be mutated by a caller writing back into the
returned rows.
- admin-org-timelines.controller.addPhase: cast to PhaseCompletionType
(already imported) instead of a hardcoded string union — stays in sync
with the Prisma enum automatically when a new type is added.
- timeline.prisma: document the NULL-distinct behavior of the
(frameworkId, templateKey) unique constraint so it's not misread as a
bug. Rows without explicit keys are already covered by the
(frameworkId, trackKey, cycleNumber) constraint above.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(flags): add FF tests + guard invalid POSTHOG_HOST
After auditing all cubic review threads, only two were actually still
open against the current code:
- admin-feature-flags.service: new URL(apiHost) at line 55 could throw
if the configured host lacks a protocol (e.g. 'posthog.internal').
Wrap it in try/catch and return [] with a logged error instead of
crashing the whole list endpoint.
- admin-feature-flags.controller/service: no tests existed. Add a
controller spec covering the NotFoundException path and happy-path
delegation, plus a service spec covering: missing REST config, the
SSRF guard refusing foreign-origin pagination, multivariate variant
strings recognized as enabled, and setFlagForOrganization calling
groupIdentify + flush.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(flags): use strict host match in fetch mock to silence CodeQL
The URL filter `u.includes('us.posthog.com')` could match `evil.com/us.posthog.com/`.
Harmless in a unit test but CodeQL flags the pattern. Switch to
`new URL(u).host === 'us.posthog.com'` so it's an exact-host check.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(app): stop tracking generated Prisma client
apps/app/.gitignore had src/generated/ but not prisma/src/generated/,
which is where the schema's output setting actually writes. A previous
merge-conflict sweep committed ~96 generated files. Extend the gitignore
and untrack them — postinstall runs 'prisma generate' so the client is
recreated on install / build.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(db): squash 9 timeline migrations into one via prisma migrate diff
Generated a single migration using 'prisma migrate diff' with
--from-migrations pointing at a copy of packages/db/prisma/migrations
that excludes the 9 timeline ones, and --to-schema pointing at the
current schema. The resulting SQL is byte-for-byte what main + the
squashed migration would produce (verified: migrate diff from the
final migrations dir against the schema reports 'No difference
detected').
Dropped:
- 20260410130000_add_timeline_models
- 20260410130001_add_phase_group_label
- 20260410130002_add_auto_policies_people_completion_types
- 20260413182638_add_timeline_lock_flags
- 20260413200000_add_timeline_lock_state_and_regression
- 20260413212000_add_timeline_template_progression_keys
- 20260413231500_add_timeline_track_keys
- 20260414113000_add_auto_findings_completion_type
- 20260417155556_timeline
Replaced with:
- 20260420000000_timeline_feature
Local devs who already applied any of the dropped migrations will need
to 'prisma migrate reset' — the old names still sit in their
_prisma_migrations table. Staging/prod haven't applied yet (branch
isn't merged) so they're unaffected.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(app): remove the duplicated prisma/ setup
apps/app/prisma/ was a full duplicate of packages/db:
- client.ts was byte-identical to packages/db/src/client.ts
- prisma/schema/ duplicated packages/db/prisma/schema/ and was
already drifting (a recent timeline.prisma comment existed in
packages/db but not here)
- prisma.config.ts + postinstall + db:generate + db:getschema all
existed to sync and generate from the local duplicated schema
The app never imports @trycompai/db directly — it uses the @db
alias (351 call sites) which maps to ./prisma/{index,server}.ts.
Those files now just re-export from @prisma/client (populated by
packages/db's build) so the local schema and generation are dead code.
Dropped:
- apps/app/prisma.config.ts
- apps/app/prisma/schema/ (45 files)
- apps/app/prisma/src/ (previously-generated tree)
- package.json: build:docker prisma-generate prefix, db:generate,
db:getschema, prebuild, postinstall
- .gitignore: stale prisma/generated + prisma/schema/*.prisma rules
Kept: apps/app/prisma/{client,index,server}.ts — these wire up the
app's PrismaClient instance (with the PG adapter) and expose it via
the @db alias. packages/db doesn't export a ready-made db instance,
so these three thin files stay for now.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(db,docker): restore Prisma client generation after app prisma cleanup
When apps/app lost its own postinstall + build:docker prisma-generate
step, nothing was left to populate @prisma/client. Cubic was right that
'next build' would fail — the deps stage already uses --ignore-scripts
and PRISMA_SKIP_POSTINSTALL_GENERATE=true, so neither the app nor
packages/db generated anything.
Fix in two places:
- packages/db/package.json: add a postinstall that runs
generate-prisma-client-js. Covers local dev — 'bun install' now
populates node_modules/@prisma/client. '|| true' mirrors the app's
old pattern so installs in envs without DATABASE_URL don't fail.
- Dockerfile app-builder stage: after combine-schemas, explicitly run
generate-prisma-client-js so the Docker build gets the client too
(the deps stage skipped it intentionally).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>1 parent 0d59e8f commit 26c04d8
113 files changed
Lines changed: 12381 additions & 95 deletions
File tree
- apps
- api
- src
- admin-feature-flags
- dto
- evidence-forms
- findings
- frameworks
- integration-platform
- controllers
- services
- people
- policies
- tasks
- timelines
- dto
- app
- prisma
- schema
- src
- app
- (app)/[orgId]
- admin
- components
- organizations/[adminOrgId]/components
- timeline-templates
- [templateId]
- components
- components
- frameworks/[frameworkInstanceId]
- components
- overview
- components
- timeline
- hooks
- packages
- analytics/src
- components
- hooks
- db
- prisma
- migrations/20260420000000_timeline_feature
- schema
- docs
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
88 | 88 | | |
89 | 89 | | |
90 | 90 | | |
| 91 | + | |
91 | 92 | | |
92 | 93 | | |
93 | 94 | | |
| |||
97 | 98 | | |
98 | 99 | | |
99 | 100 | | |
| 101 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
66 | | - | |
67 | | - | |
68 | | - | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
69 | 73 | | |
70 | 74 | | |
71 | 75 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
11 | | - | |
12 | 10 | | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
13 | 15 | | |
| 16 | + | |
14 | 17 | | |
15 | 18 | | |
16 | | - | |
17 | 19 | | |
| 20 | + | |
| 21 | + | |
18 | 22 | | |
| 23 | + | |
19 | 24 | | |
| 25 | + | |
20 | 26 | | |
21 | 27 | | |
22 | 28 | | |
23 | 29 | | |
| 30 | + | |
24 | 31 | | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
25 | 36 | | |
26 | 37 | | |
27 | 38 | | |
| 39 | + | |
| 40 | + | |
28 | 41 | | |
29 | 42 | | |
30 | 43 | | |
| 44 | + | |
31 | 45 | | |
32 | 46 | | |
33 | 47 | | |
34 | 48 | | |
| 49 | + | |
| 50 | + | |
35 | 51 | | |
36 | 52 | | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
44 | | - | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | 53 | | |
57 | 54 | | |
| 55 | + | |
| 56 | + | |
58 | 57 | | |
59 | 58 | | |
60 | 59 | | |
| 60 | + | |
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
| |||
103 | 103 | | |
104 | 104 | | |
105 | 105 | | |
| 106 | + | |
106 | 107 | | |
107 | 108 | | |
108 | 109 | | |
| |||
Lines changed: 132 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
Lines changed: 69 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
Lines changed: 11 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
0 commit comments