l3montree-dev / l3montree-dev/devguard
External-provider asset sync writes `project_id = nil UUID` (FK violation)
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 161
- Forks
- 43
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 37
Description
Summary: On re-sync, syncProjectAssets stamps every asset with project.ID, but for already-existing projects the upsert returns the struct with an unpopulated (uuid.Nil) ID. Assets are written against 00000000-…, violating fk_projects_assets.
Impact: Assets fail to persist when re-syncing existing external projects (first import is fine). 163 occurrences, clustered at sync runs.
Evidence (prod):
ERROR: insert or update on table "assets" violates foreign key constraint "fk_projects_assets"
DETAIL: Key (project_id)=(00000000-0000-0000-0000-000000000000) is not present in table "projects".
All 163 are the zero UUID, all UPDATE "assets" (conflict-update branch).
Root cause:
- Provider projects arrive with no DB id —
upsertProjectssets onlyOrganizationID. UpsertSplitupserts on(external_entity_provider_id, external_entity_id); conflict-update (existing) rows don't get theirIDpopulated back, yet are returned inupdatedProjects.syncProjectAssets:306trusts it:assets[i].ProjectID = project.ID(=uuid.Nil).
Always exactly the zero UUID, only on re-sync — not a race against a real project.
Reproduce:
docker exec -i devguard-postgresql-1 psql -U devguard -d devguard <<'SQL'
BEGIN;
UPDATE assets SET project_id = '00000000-0000-0000-0000-000000000000'
WHERE id = (SELECT id FROM assets LIMIT 1);
ROLLBACK;
SQL
# => ERROR: ... violates foreign key constraint "fk_projects_assets"
# DETAIL: Key (project_id)=(00000000-...0000) is not present in table "projects".
App-level: configure an external provider and run the project sync twice.
Fix: populate IDs for updated projects in UpsertSplit (re-select by external keys, map id back); guard syncProjectAssets to skip when project.ID == uuid.Nil.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in services/external_entity_provider_service.go at upsertProjects and syncProjectAssets, then inspect UpsertSplit in database/repositories/project_repository.go around the referenced lines. Run the project sync twice with an external provider and verify existing projects retain populated IDs before assets are written, with zero-UUID asset writes prevented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, postgresql
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100