Skip to content

feat: add membership_type column to storage_module for multi-scope storage#58

Merged
pyramation merged 1 commit intomainfrom
devin/1776587132-storage-module-multi-scope
Apr 19, 2026
Merged

feat: add membership_type column to storage_module for multi-scope storage#58
pyramation merged 1 commit intomainfrom
devin/1776587132-storage-module-multi-scope

Conversation

@pyramation
Copy link
Copy Markdown
Contributor

Summary

Updates the storage_module table schema to support multi-scope (multi-tenant) storage. This syncs the published metaschema-modules package with the schema changes already merged in constructive-db (PR #876).

Changes to storage_module/table.sql:

  1. New column membership_type int DEFAULT NULL — discriminates storage scope:

    • NULL = app-level storage (gated by AuthzMembership via app_sprt)
    • Non-NULL = entity-scoped storage (gated by AuthzEntityMembership, value matches the entity's membership type)
  2. Renamed default table namesbuckets/files/upload_requestsapp_buckets/app_files/app_upload_requests to clearly identify database-level (app-scope) storage tables vs entity-scoped ones.

  3. New unique index storage_module_unique_scope on (database_id, COALESCE(membership_type, -1)) — enforces at most one storage module per scope per database (one app-level + one per membership type).

Why: constructive PR #1009 adds multi-scope bucket resolution to the GraphQL plugins, which queries storage_module.membership_type. CI fails because the published package doesn't have this column yet. Publishing this update unblocks that PR.

Review & Testing Checklist for Human

  • Verify the schema matches constructive-db exactly — compare this file against constructive-db/pgpm-modules/metaschema-modules/deploy/.../storage_module/table.sql on main to confirm no drift
  • Confirm the default name rename is intentional — changing from 'buckets'/'files'/'upload_requests' to 'app_buckets'/'app_files'/'app_upload_requests' affects all newly provisioned databases
  • Validate the COALESCE(-1) sentinel — the unique index uses COALESCE(membership_type, -1) to treat NULL as a distinct value; confirm -1 will never be a valid membership_type

Notes

  • Verify and revert scripts are unchanged — verify_table() still works since the table name hasn't changed, and revert is a DROP TABLE.
  • This is a CREATE TABLE deploy script, not an ALTER TABLE migration. Existing databases will need a separate migration to add the column and index.

Link to Devin session: https://app.devin.ai/sessions/18879be982854a40abe5c9b915aa4a84
Requested by: @pyramation

…orage

- Add membership_type int column (NULL = app-level AuthzMembership, non-NULL = entity-scoped AuthzEntityMembership)
- Rename default table names from buckets/files/upload_requests to app_buckets/app_files/app_upload_requests
- Add unique index on (database_id, COALESCE(membership_type, -1)) to enforce one module per scope
- Update entity_table_id comment to reflect app-level vs entity-scoped usage

Syncs with constructive-db PR #876 (merged).
@devin-ai-integration
Copy link
Copy Markdown

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@pyramation pyramation merged commit 12902ee into main Apr 19, 2026
24 checks passed
@pyramation pyramation deleted the devin/1776587132-storage-module-multi-scope branch April 19, 2026 08:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant