Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.
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
4 changes: 2 additions & 2 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ Vrij en open source onder de EUPL-1.2-licentie.
<repair-steps>
<install>
<step>OCA\OpenBuilt\Repair\InitializeSettings</step>
<step>OCA\OpenBuilt\Repair\SeedHelloWorld</step>
<step>OCA\OpenBuilt\Repair\MigrateToVersionedModel</step>
<step>OCA\OpenBuilt\Repair\PopulateApplicationPermissions</step>
<step>OCA\OpenBuilt\Repair\SeedApplicationTemplates</step>
</install>
<post-migration>
<step>OCA\OpenBuilt\Repair\InitializeSettings</step>
<step>OCA\OpenBuilt\Repair\SeedHelloWorld</step>
<step>OCA\OpenBuilt\Repair\MigrateToVersionedModel</step>
<step>OCA\OpenBuilt\Repair\PopulateApplicationPermissions</step>
<step>OCA\OpenBuilt\Repair\SeedApplicationTemplates</step>
</post-migration>
Expand Down
12 changes: 12 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@
// Specific route MUST precede the SPA catch-all (memory rule: Symfony specific-first).
['name' => 'applications#diffVersions', 'url' => '/api/applications/{slug}/versions/diff', 'verb' => 'GET', 'requirements' => ['slug' => '[a-z0-9][a-z0-9-]*[a-z0-9]']],

// ApplicationVersion CRUD + strategy-aware delete (spec
// `application-versions` REQ-OBV-107 / REQ-OBV-108 of
// openbuilt-versioning-model). Specific routes MUST precede the
// SPA catch-all to win Symfony's order-sensitive router (memory
// rule: specific-first). The `/diff` route above stays first
// because its URL is more specific than `{versionSlug}`.
['name' => 'applicationVersions#index', 'url' => '/api/applications/{slug}/versions', 'verb' => 'GET', 'requirements' => ['slug' => '[a-z0-9][a-z0-9-]*[a-z0-9]']],
['name' => 'applicationVersions#create', 'url' => '/api/applications/{slug}/versions', 'verb' => 'POST', 'requirements' => ['slug' => '[a-z0-9][a-z0-9-]*[a-z0-9]']],
['name' => 'applicationVersions#show', 'url' => '/api/applications/{slug}/versions/{versionSlug}', 'verb' => 'GET', 'requirements' => ['slug' => '[a-z0-9][a-z0-9-]*[a-z0-9]', 'versionSlug' => '[a-z0-9][a-z0-9-]*[a-z0-9]']],
['name' => 'applicationVersions#update', 'url' => '/api/applications/{slug}/versions/{versionSlug}', 'verb' => 'PUT', 'requirements' => ['slug' => '[a-z0-9][a-z0-9-]*[a-z0-9]', 'versionSlug' => '[a-z0-9][a-z0-9-]*[a-z0-9]']],
['name' => 'applicationVersions#destroy', 'url' => '/api/applications/{slug}/versions/{versionSlug}', 'verb' => 'DELETE', 'requirements' => ['slug' => '[a-z0-9][a-z0-9-]*[a-z0-9]', 'versionSlug' => '[a-z0-9][a-z0-9-]*[a-z0-9]']],

// Export pipeline (Phase-2 graduation).
['name' => 'exports#submit', 'url' => '/api/applications/{slug}/exports', 'verb' => 'POST', 'requirements' => ['slug' => '[a-z0-9][a-z0-9-]*[a-z0-9]']],
['name' => 'exports#download', 'url' => '/api/exports/{uuid}/download', 'verb' => 'GET'],
Expand Down
31 changes: 22 additions & 9 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@

namespace OCA\OpenBuilt\AppInfo;

use OCA\OpenBuilt\Listener\ApplicationVersionSnapshotListener;
use OCA\OpenBuilt\Listener\ProductionVersionGuardListener;
use OCA\OpenBuilt\Listener\DeepLinkRegistrationListener;
use OCA\OpenBuilt\Mcp\OpenBuiltToolProvider;
use OCA\OpenRegister\Event\DeepLinkRegistrationEvent;
use OCA\OpenRegister\Event\ObjectTransitionedEvent;
use OCA\OpenRegister\Event\ObjectCreatingEvent;
use OCA\OpenRegister\Event\ObjectUpdatingEvent;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
Expand Down Expand Up @@ -69,13 +70,25 @@ public function register(IRegistrationContext $context): void
listener: DeepLinkRegistrationListener::class
);

// Snapshot the Application's manifest into ApplicationVersion on
// draft→published transitions (chain spec #6 openbuilt-versioning,
// ADR-031 §Exceptions(1) — declarative-first fallback because OR's
// engine does not yet execute on_transition.create_relation).
// Per ADR-002 the snapshot-on-publish writeback listener has been
// retired. ApplicationVersion is now a first-class long-lived row,
// not an append-only snapshot, and `Application.currentVersion` has
// been removed in favour of an explicit `productionVersion` relation
// set by the admin. Object time-travel on the ApplicationVersion row
// captures audit history. The corresponding spec retirement lives
// in openbuilt-versioning-model/specs/openbuilt-version-snapshots.
// Cross-row integrity guard: on every Application save (create or
// update), verify that `productionVersion` (when set) points at an
// ApplicationVersion whose `application` relation refers back to
// this Application (ADR-031 §Exceptions(1) — cross-row validation
// that OR's per-row x-openregister-validation cannot perform).
$context->registerEventListener(
event: ObjectTransitionedEvent::class,
listener: ApplicationVersionSnapshotListener::class
event: ObjectCreatingEvent::class,
listener: ProductionVersionGuardListener::class
);
$context->registerEventListener(
event: ObjectUpdatingEvent::class,
listener: ProductionVersionGuardListener::class
);

// Register OpenBuiltToolProvider as the MCP tool provider for the AI Chat Companion.
Expand All @@ -88,7 +101,7 @@ public function register(IRegistrationContext $context): void
OpenBuiltToolProvider::class
);

// Repair steps (InitializeSettings + SeedHelloWorld) are declared in info.xml.
// Repair steps (InitializeSettings + MigrateToVersionedModel + …) are declared in info.xml.
}//end register()

/**
Expand Down
Loading
Loading