Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,31 @@ The `open_educational_resources` table stores processed OER data with denormaliz
| `amb_date_created` | Timestamp | Yes | AMB Event | Resource creation date |
| `amb_date_published` | Timestamp | Yes | AMB Event | Publication date |
| `amb_date_modified` | Timestamp | Yes | AMB Event | Last modification date (for update tracking) |
| **Event References** |
| `event_amb_id` | Text | Yes, FK | System | Foreign key to AMB event in `nostr_events` |
| `event_file_id` | Text | Yes, FK | System | Foreign key to file event in `nostr_events` (nullable) |
| **System Fields** |
| `created_at` | Timestamp | Yes | System | Record creation timestamp |
| `updated_at` | Timestamp | - | System | Last update timestamp |
| `source` | Text | Yes | System | Origin identifier (e.g., "nostr") |
| `source_name` | Text | Yes | System | Origin identifier (e.g., "nostr") |
| `name` | Text | - | AMB Event | Resource name/title |
| `attribution` | Text | - | AMB Event | Attribution/copyright notice |

### OER Sources Table

The `oer_sources` table stores raw Nostr events and links them to OER records:

| Field | Type | Description |
|-------|------|-------------|
| `id` | UUID | Auto-generated primary key |
| `oer_id` | UUID | Foreign key to `open_educational_resources` (nullable, cascade delete) |
| `source_name` | Text | Origin identifier (e.g., "nostr") |
| `source_identifier` | Text | Unique identifier (e.g., `event:<event-id>`) |
| `source_data` | JSONB | Complete raw event data |
| `status` | Text | Processing status: `pending` or `processed` |
| `source_uri` | Text | Resource URI from the event |
| `source_timestamp` | BigInt | Event timestamp (created_at) |
| `source_record_type` | Text | Event kind (e.g., "30142", "1063") |
| `created_at` | Timestamp | Record creation timestamp |
| `updated_at` | Timestamp | Last update timestamp |

**Design Rationale**:
- **Denormalization**: Frequently queried fields are extracted from events for indexing, enabling fast searches by license, level, audience, and dates
- **JSONB Storage**: Complete AMB metadata is preserved to avoid data loss and support future query needs without schema changes
Expand Down
15 changes: 8 additions & 7 deletions docs/nostr-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,11 @@ Events may arrive in any order and are processed independently:

## Event Storage

All Nostr events (kinds 30142, 1063, and deletion events) are stored in the `nostr_events` table with:
- Complete raw event data (JSONB format)
- Indexed fields for efficient querying (event ID, kind, pubkey, created_at)
- Source relay URL for traceability
- Ingestion timestamp for auditing

Events are retained until explicitly deleted via NIP-09 deletion events.
All Nostr events (kinds 30142, 1063, and deletion events) are stored in the `oer_sources` table with:
- Complete raw event data in `source_data` (JSONB format)
- Source identifier (`event:<event-id>`) for lookups
- Record type (event kind) for filtering
- Processing status (`pending`, `processed`)
- Link to OER record when processed

Events are linked to their corresponding OER records via the `oer_id` foreign key. When an OER is deleted, all associated sources are cascade-deleted.
12 changes: 6 additions & 6 deletions openspec/specs/aggregator-server/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -409,13 +409,13 @@ The application MUST handle kind 5 (NIP-09) deletion events from Nostr relays, v
- **AND** the deletion is logged with event ID and kind
- **AND** all related data is removed atomically

#### Scenario: Nullify file metadata for deleted file events
#### Scenario: Handle file event deletion
- **GIVEN** a valid deletion request for a kind 1063 (file) event
- **WHEN** the file event is deleted
- **THEN** file metadata fields (file_mime_type, file_size, file_dim, file_alt) are nullified in all OER records referencing this file
- **AND** the file event reference (event_file_id) is set to null by database constraint
- **AND** the OER records remain intact with nullified file metadata
- **AND** the deletion is logged with affected OER count
- **WHEN** the file event source is deleted
- **THEN** the file event source is removed from the `oer_sources` table
- **AND** file metadata fields on the OER record are not automatically nullified
- **AND** the OER record remains intact
- **AND** the deletion is logged

#### Scenario: Delete other event types directly
- **GIVEN** a valid deletion request for an event that is not AMB or file type
Expand Down
11 changes: 3 additions & 8 deletions packages/oer-finder-api-client/dist/generated/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,15 +458,10 @@ export interface components {
*/
source: string;
/**
* @description Nostr event ID for the AMB event
* @example abc123def456
* @description URL to the resource landing page on the original source website (e.g., Openverse, Flickr)
* @example https://www.flickr.com/photos/12345/67890
*/
event_amb_id: Record<string, never> | null;
/**
* @description Nostr event ID for the file event
* @example xyz789uvw012
*/
event_file_id: Record<string, never> | null;
foreign_landing_url: string | null;
/**
* Format: date-time
* @description Timestamp when the record was created in the database
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading