Configurations
Configurations in OpenRegister allow you to package and manage related registers, schemas, and objects together as a coherent unit. This feature is particularly useful for multi-tenancy, application packaging, and organizing complex data structures.
Overview
A Configuration is a container that groups together:
- Registers: Collections of objects that share similar characteristics
- Schemas: Data structure definitions that define object properties
- Objects: Individual data items (optional)
Key Concepts
Configuration Properties
Each configuration has the following properties:
- Title: A human-readable name for the configuration
- Description: Detailed description of what the configuration contains
- Type: The type or category of the configuration (e.g., 'application', 'tenant', 'module')
- Owner/App: The application or owner identifier
- Registers: Array of register IDs that are part of this configuration
- Schemas: Array of schema IDs that are part of this configuration
- Objects: Array of object IDs that are part of this configuration (optional)
- Version: Configuration version for tracking changes
- Created/Updated: Timestamps for auditing
Use Cases
Application Packaging
Package all registers and schemas for a specific application:
Multi-Tenancy
Create separate configurations for different tenants:
Module Organization
Group related functionality into logical modules:
- Core Module: Base registers and schemas
- Customer Module: Customer-related data structures
- Product Module: Product catalog structures
- Order Module: Order processing structures
Creating a Configuration
Step 1: Navigate to Configurations
- Log in to your Nextcloud instance
- Navigate to the OpenRegister app
- Click on Configurations in the left sidebar
Step 2: Add New Configuration
- Click the Add Configuration button
- Fill in the configuration details:
- Title: Give your configuration a meaningful name
- Description: Describe what this configuration contains
- Type: Specify the configuration type (e.g., 'application', 'tenant')
Step 3: Select Registers and Schemas
-
Select Registers:
- Click on the Registers dropdown
- Select multiple registers that should be part of this configuration
- The count of selected registers is displayed below the selector
-
Select Schemas:
- Click on the Schemas dropdown
- Select multiple schemas that should be part of this configuration
- The count of selected schemas is displayed below the selector
Step 4: Save the Configuration
- Review your selections
- Click the Save button
- The configuration is created and added to the list
Editing a Configuration
Modifying Configuration Details
- Navigate to the Configurations page
- Find the configuration you want to edit
- Click the Actions menu (three dots)
- Select Edit
- Modify the fields as needed:
- Update title, description, or type
- Add or remove registers
- Add or remove schemas
- Click Save to apply changes
Managing Associations
You can dynamically manage which registers and schemas are associated with a configuration:
- Add new associations: Select additional items from the dropdowns
- Remove associations: Deselect items from the dropdowns
- View current associations: The modal shows all currently selected items
Viewing Configurations
Card View
The card view displays configurations as cards showing:
- Configuration title
- Description
- Type
- Owner/App
- Count of associated items (registers, schemas, objects)
Table View
The table view shows configurations in a tabular format with columns:
- Title
- Type
- Owner
- Config Keys count
- Created date
- Updated date
- Actions
Switch between views using the Cards / Table toggle buttons.
Exporting and Importing Configurations
Exporting
- Select a configuration
- Click Actions → Export
- The configuration (including its registers, schemas, and optionally objects) is exported as JSON
- Use this for:
- Backup and restore
- Moving configurations between environments
- Sharing configurations with other installations
Importing
- Click Import Configuration
- Select a configuration JSON file
- Choose whether to include objects
- The configuration and its associated items are imported
Local vs External Configurations
OpenRegister distinguishes between two types of configurations:
Local Configurations
Local configurations are created and maintained within your Nextcloud installation. These are configurations you own and control.
Characteristics:
- Created using the 'Create Configuration' button
- Maintained and updated within your installation
- Marked with a green 'Local' pill in the UI
- Can be exported to share with others
- Version is managed by you
External Configurations
External configurations are imported from external sources and kept in sync with their origin. These are configurations created by others that you import and use.
Characteristics:
- Imported from GitHub, GitLab, or URLs
- Marked with a blue 'External' pill in the UI
- Can be automatically synchronized
- Read-only (modifications would be overwritten on sync)
- Version controlled by the source
Sync Status Indicators
External configurations display sync status badges showing:
- Synced just now: Recently synchronized
- Synced 2h ago: Time since last sync
- Sync failed: Last sync attempt failed
- Never synced: No sync performed yet
Discovering and Importing Configurations
OpenRegister provides multiple ways to discover and import configurations from external sources:
Discovery from GitHub/GitLab
OpenRegister uses a two-phase discovery approach for optimal global discovery and content validation:
Phase 1: Organization Discovery (Path-based)
- Searches globally for ANY files containing 'openregister' in the filename or path
- Identifies all organizations/users that have OpenRegister-related files
- No organization restrictions - searches all public repositories
- Discovers via configuration files (
*_openregister.json) OR documentation files (openregister.md) - Processes up to 500 files (first 5 pages × 100 results)
- Limits to top 50 organizations for scalability
Phase 2: Content Validation (Batched)
- Searches within discovered organizations for JSON files containing 'x-openregister'
- Validates that files are actual OpenRegister configurations
- Uses batched searches (10 organizations per batch) to handle query length limits
- Filters out false positives automatically
- Results sorted by repository popularity (stars)
- Proper pagination support
Benefits:
- ✅ Truly global discovery - automatically finds new organizations
- ✅ Content validation - ensures files are real OpenRegister configs
- ✅ No hardcoded lists - organizations are dynamically discovered
- ✅ Very flexible - discovers via config files OR documentation files
- ✅ Scalable - handles hundreds of organizations via batching
- ✅ Performant - optimized pagination and result sorting
- ✅ Rich metadata - provides organization info, raw URLs, and actual configuration details
- ✅ Automatic enrichment - cards load instantly and enrich details in the background
- ✅ Zero API rate limit impact - uses raw.githubusercontent.com for enrichment
Card Display:
Each discovered configuration is displayed as a card with:
- Title: From
info.titlein the configuration file (or filename as fallback) - Loading State: Shows 'Obtaining additional information...' with loading icon
- Description: From
info.descriptionin the configuration file - Repository Link: Clickable link to the GitHub repository
- Organization Link: Clickable link to the organization/owner page
- Stars: Repository popularity indicator
- Actions: Import and View Source buttons
The card automatically fetches full configuration details when displayed, showing a loading state initially and updating with real data once retrieved.
Steps:
- Click Import Configuration
- Select the Discover tab
- Enter search terms (optional) - searches in filename, repository, title, description
- Click Search GitHub or Search GitLab
- Browse discovered configurations from across GitHub/GitLab
- Click Import on any configuration
How to make your configuration discoverable:
Option 1: Configuration File (Preferred)
- Filename: Include 'openregister' in your JSON filename (e.g.,
myapp_openregister.json) - Content: Ensure your JSON file contains the 'x-openregister' property
- Public repository: File must be in a public GitHub/GitLab repository
Option 2: Documentation File
- Add an
openregister.mdfile to your repository - Still include your configuration JSON file (e.g.,
myapp_openregister.json) - The
openregister.mdhelps discovery, but the JSON file is what gets imported
Note on naming:
- Configuration files: We recommend
*_openregister.jsonpattern (e.g.,myapp_openregister.json) - Documentation files: Use
openregister.mdto make your repository more discoverable - Any file with 'openregister' in the path will trigger organization discovery
Alternative import methods:
- Import from GitHub tab: Browse any repository directly and select any JSON file
- Import from URL tab: Use the raw GitHub URL (e.g.,
https://raw.githubusercontent.com/owner/repo/branch/path/to/file.json)
Import from Specific Repository
- Click Import Configuration
- Select the GitHub / GitLab tab
- Select source platform (GitHub or GitLab)
- Enter repository details:
- For GitHub: Owner and Repository name
- For GitLab: Namespace and Project name
- Click Load Branches
- Select a branch
- Choose a configuration file from the list
- Configure sync settings
- Click Import
Import from Direct URL
- Click Import Configuration
- Select the Import from URL tab
- Enter the direct URL to a JSON configuration file
- Configure sync settings:
- Enable automatic synchronization
- Set sync interval (in hours)
- Click Import
Getting the raw URL from GitHub:
- Navigate to your file on GitHub
- Click the Raw button (top right of the file viewer)
- Copy the URL from your browser's address bar
- Example format:
https://raw.githubusercontent.com/owner/repo/branch/path/to/file.json
Tip: This method works immediately after pushing - no need to wait for GitHub's search index!
File Naming Conventions for Discoverability
To make your configurations discoverable by others, include 'openregister' in your JSON filename:
Recommended File Names
- Preferred format:
{app}_openregister.json(e.g.,myapp_openregister.json) - Alternative formats:
{app}.openregister.json,openregister.{app}.json - Simple format:
openregister.json(works but less specific)
Examples
# Preferred (with underscore)
softwarecatalogus_openregister.json
publication_openregister.json
customer_management_openregister.json
# Also works (without underscore)
opencatalogi.openregister.json
publication-register.openregister.json
customer-management.openregister.json
openregister.json
Why the underscore (_) is preferred:
- More explicit pattern for OpenRegister configurations
- Avoids confusion with legacy OpenAPI specification files
- Consistent convention across all apps
- Recommended but not required - all patterns above work!
File Location
Place configuration files in a logical location within your repository:
my-app/
├── lib/
│ └── Settings/
│ └── my-app.openregister.json
├── config/
│ └── openregister.json
└── README.md
Metadata for Discovery
Ensure your configuration includes proper metadata in the 'x-openregister' section:
{
'openapi': '3.0.0',
'info': {
'title': 'My App Configuration',
'description': 'Configuration for my awesome application',
'version': '1.0.0'
},
'x-openregister': {
'type': 'application',
'app': 'myapp',
'sourceType': 'github',
'sourceUrl': 'https://github.com/MyOrg/myapp/blob/main/lib/Settings/myapp_openregister.json',
'openregister': '^v0.2.10',
'github': {
'repo': 'MyOrg/myapp',
'branch': 'main',
'path': 'lib/Settings/myapp_openregister.json'
}
},
'components': {
'registers': {},
'schemas': {}
}
}
Key requirements for discoverability:
- Filename: Must contain 'openregister' (e.g.,
myapp_openregister.json) - x-openregister property: Must be present in the JSON file (triggers Phase 2 validation)
- Public repository: File must be accessible in a public GitHub/GitLab repository
- Valid JSON: File must be valid JSON and follow the OpenAPI 3.0 structure
Making Configurations Discoverable
For your configuration to be discoverable via GitHub/GitLab search in OpenRegister, follow these requirements:
1. File Structure
Your configuration file MUST be a valid OpenAPI 3.0 document with an 'x-openregister' extension:
{
'openapi': '3.0.0',
'info': {
'title': 'Required: Configuration Title',
'description': 'Required: Detailed description',
'version': 'Required: Semantic version (e.g., 1.0.0)'
},
'x-openregister': {
'type': 'Required: Type of configuration (application/tenant/module)',
'app': 'Required: Application identifier',
'sourceType': 'Required: github or gitlab',
'sourceUrl': 'Required: Full URL to this file',
'openregister': 'Optional: Version constraint (e.g., ^v0.2.10)',
'github': {
'repo': 'Required: owner/repository',
'branch': 'Required: branch name',
'path': 'Required: path to file in repo'
}
},
'components': {
'registers': {},
'schemas': {}
}
}
2. File Naming Convention for Discovery
How OpenRegister Discovery Works:
OpenRegister uses a two-phase discovery approach for reliable global configuration discovery:
Phase 1: Organization Discovery (Filename-based)
- Searches for JSON files containing 'openregister' in the filename or path
- Works globally across all public repositories (no organization restrictions!)
- Discovers organizations/users that have potential OpenRegister files
Phase 2: Content Validation
- Searches within discovered organizations for files containing 'x-openregister'
- Validates that files are actual OpenRegister configurations
- Filters out false positives automatically
File Naming Requirements:
Your configuration filename MUST contain 'openregister' to be discoverable:
- ✅ Preferred:
*_openregister.json(e.g.,myapp_openregister.json) - ✅ Also works:
*.openregister.json,openregister.*.json,openregister.json - ✅ For discovery boost: Add
openregister.mddocumentation file to your repository
Why _openregister.json is preferred:
- More explicit pattern for OpenRegister configurations
- Avoids confusion with legacy OpenAPI specification files
- Consistent convention recommended across all apps
- But any filename containing 'openregister' works!
Using openregister.md for enhanced discovery:
- Adding an
openregister.mdfile makes your repository more discoverable - Useful for documenting your OpenRegister configuration
- Phase 1 will find your org via the .md file
- Phase 2 still validates your .json configuration file
- Both files working together = maximum discoverability!
Content Requirements (Phase 2 Validation):
- Configuration file MUST contain an 'x-openregister' property in the JSON
- This is what validates your file as a real OpenRegister configuration
- Files without 'x-openregister' will be filtered out even if the filename matches
Discovery Indexing:
- New files are typically indexed within minutes to hours after pushing to GitHub
- Renamed files are re-indexed automatically
- No waiting period or organization approval needed!
Testing Discovery:
After pushing your file, test it appears in OpenRegister:
- Go to Import Configuration → Discover tab
- Search for keywords from your filename, title, or description
- Your configuration should appear in global results
- If it doesn't appear immediately, wait a few hours for GitHub to index it
3. Required Fields
info section:
- 'title': Short, descriptive name shown in discovery results
- 'description': Detailed explanation of what the configuration provides
- 'version': Semantic version number (1.0.0, 2.1.3, etc.)
x-openregister section:
- 'type': Configuration type ('application', 'tenant', 'module', etc.)
- 'app': Application identifier (lowercase, no spaces)
- 'sourceType': Must be 'github' or 'gitlab' for discovery
- 'sourceUrl': Complete HTTPS URL to the file on GitHub/GitLab
- 'github' or 'gitlab': Object with 'repo', 'branch', and 'path'
Optional fields:
- 'openregister': Minimum OpenRegister version required (Composer notation)
3. File Naming Conventions
For best discoverability, use one of these naming patterns:
- '*_openregister.json' (recommended): 'myapp_openregister.json'
- 'openregister.json': Generic name
- '*.openregister.json': 'config.openregister.json'
4. Complete Example
Here's a complete, production-ready example:
{
'openapi': '3.0.0',
'info': {
'title': 'VNG Software Catalog Register',
'description': 'Register containing AMEF and Voorzieningen schemas for the VNG Software Catalog application. This configuration includes schemas for modules, services, organizations, and compliance tracking.',
'version': '2.0.1'
},
'x-openregister': {
'type': 'application',
'app': 'softwarecatalog',
'sourceType': 'github',
'sourceUrl': 'https://github.com/ConductionNL/opencatalogi/blob/master/apps-extra/softwarecatalog/lib/Settings/softwarecatalogus_register.json',
'openregister': '^v0.2.10',
'github': {
'repo': 'ConductionNL/opencatalogi',
'branch': 'master',
'path': 'apps-extra/softwarecatalog/lib/Settings/softwarecatalogus_register.json'
}
},
'components': {
'registers': {
'products': {
'slug': 'products',
'title': 'Products',
'description': 'Product catalog register',
'schemas': ['product']
}
},
'schemas': {
'product': {
'title': 'Product',
'description': 'Product schema',
'properties': {
'name': {'type': 'string'},
'price': {'type': 'number'}
}
}
}
}
}
5. Testing Discoverability
After publishing your configuration file to GitHub/GitLab:
- Verify your filename: Ensure your file ends with
_openregister.json(e.g.,app_openregister.json) - Push to GitHub: Commit and push your configuration file
- Wait for indexing: GitHub typically indexes new files within minutes to a few hours
- Test discovery: In OpenRegister, click Import Configuration → Discover tab
- Search: Enter keywords from your filename, title, or description
- Verify: Your configuration should appear in the global results
Troubleshooting:
- Not appearing in discovery?
- Check filename: Does it end with
_openregister.json? (e.g.,myapp_openregister.json) - Wrong pattern: Files named just
openregister.json(without prefix) won't be discovered - Wait for indexing: New files may take a few hours to appear in GitHub's search index
- Test file exists: Visit your file URL directly on GitHub to confirm it's pushed
- Use alternative import methods: 'Import from URL' or 'Import from GitHub' (by repository) work immediately for any public repository
- Check filename: Does it end with
- Need immediate access? Use the 'Import from GitHub' tab and browse your repository directly, or use 'Import from URL' with the raw file URL
- Validate your JSON structure
- Ensure all required fields are present
- Check that 'sourceUrl' is accessible publicly
- Verify the 'x-openregister' extension is at the root level
- Confirm the file is on a public repository (or you've configured API tokens)
6. API Tokens for Private Repositories
You can use private repositories for your configurations as long as your GitHub/GitLab Personal Access Token has access to them. This allows you to:
- Publish configurations to private repositories
- Import configurations from private repositories
- Discover configurations in private repositories (if your token has access)
Setting up API Tokens:
- Navigate to Settings → OpenRegister Settings
- Scroll to API Token Configuration
- Enter your GitHub or GitLab Personal Access Token
- Required scopes:
- GitHub: 'repo' (for full access to public and private repositories)
- GitLab: 'read_api' (discovery only) or 'api' (discovery + publishing)
How Private Repositories Work:
- Repository Access: Your token must have access to the repository (you must be a collaborator or have access through organization membership)
- Discovery: Private repositories will appear in search/discovery results only if your token has access to them
- Publishing: You can publish to any repository (public or private) that your token has write access to
- Importing: You can import from any repository (public or private) that your token has read access to
- Token Scope: The 'repo' scope for GitHub provides access to both public and private repositories you have access to
Note: Each user must configure their own token. If you want to share a private repository configuration with others, they need to:
- Have access to the repository on GitHub/GitLab
- Configure their own API token with access to that repository
- The repository will then appear in their discovery/search results
7. Publishing Updates
When you update your configuration:
- Increment the 'version' in the 'info' section
- Commit and push the changes
- External installations with auto-sync will automatically receive updates
- Manual imports will see an 'Update Available' badge
OpenRegister Version Requirements
Configurations can specify which OpenRegister versions they are compatible with using Composer-style notation:
Version Constraint Format
Use the 'openregister' field in 'x-openregister':
{
'x-openregister': {
'openregister': '^v0.2.10'
}
}
Supported Constraint Formats
Following Composer notation:
- Caret (^): '^v1.2.3' - Allow version 1.2.3 and up, but not 2.0.0
- Tilde (~): '~1.2.3' - Allow version 1.2.3 to 1.3.0 (excluding)
- Exact: 'v1.2.3' - Only version 1.2.3
- Greater/Less: '>=1.2.0' - Version 1.2.0 or higher
- Range: '>=1.0.0 <2.0.0' - Between 1.0.0 and 2.0.0
Examples
// Require v0.2.10 or higher (but not v0.3.0)
{'openregister': '^v0.2.10'}
// Require at least v1.0.0
{'openregister': '>=v1.0.0'}
// Require between v1.0 and v2.0
{'openregister': '>=v1.0.0 <v2.0.0'}
// Exact version
{'openregister': 'v1.5.0'}
Automatic Synchronization
External configurations can be automatically synchronized with their source to keep them up-to-date.
Configuring Auto-Sync
When importing a configuration from GitHub, GitLab, or URL:
- Enable the Enable automatic synchronization toggle
- Set the Sync Interval (in hours, 1-168)
- Complete the import
Sync Behavior
- Check Interval: OpenRegister checks for updates based on the configured interval
- Version Comparison: Compares local and remote versions
- Automatic Update: If a new version is available, automatically imports it
- Status Tracking: Records sync status and timestamp
- Error Handling: Failed syncs are logged and displayed in the UI
Manual Sync
You can also manually trigger a sync:
- Navigate to Configurations
- Find the external configuration
- Click Actions → Check Version
- If an update is available, you'll be notified
Sync Frequency
Recommended intervals based on use case:
- Production: 24-48 hours
- Development: 1-6 hours
- Testing: 1-2 hours
Publishing Local Configurations
OpenRegister allows you to publish your local configurations directly to GitHub repositories. This makes it easy to share configurations with others and keep them synchronized across installations.
Publishing to GitHub
You can publish local configurations directly to GitHub from within OpenRegister:
- Navigate to Configurations
- Find the local configuration you want to publish
- Click Actions → Publish (or Update Published if already published)
- In the publish dialog:
- Select Repository: Choose from repositories your GitHub token has access to
- Select Branch: Choose the branch to publish to (e.g., 'main', 'develop')
- File Path: Enter the path where the configuration file should be saved (e.g.,
lib/Settings/config.json) - Commit Message: Enter a descriptive commit message
- Click Publish
The configuration will be exported and committed to the selected repository. Once published, the configuration will show a red 'Published' badge.
File structure example:
my-repository/
├── lib/
│ └── Settings/
│ └── myapp_openregister.json
└── README.md
Private Repositories
You can publish to private repositories as long as your GitHub Personal Access Token has access to them:
-
Configure GitHub Token:
- Navigate to Settings → OpenRegister Settings
- Scroll to API Token Configuration
- Enter your GitHub Personal Access Token with 'repo' scope
-
Token Permissions:
- The token must have 'repo' scope for full access (read and write)
- This allows access to both public and private repositories you have access to
- Private repositories will appear in the repository selector if your token has access
-
Publishing to Private Repos:
- Private repositories will appear in the repository dropdown
- They are marked with '(Private)' in the list
- Publishing works the same way as public repositories
- Only users with access to the repository (via their token) can import from it
Note: When importing from private repositories, users must also configure their GitHub token with access to that repository. The repository will only appear in discovery/search results if the user's token has access to it.
Updating Published Configurations
If a configuration is already published:
- Make your changes locally
- Click Actions → Update Published
- The same dialog opens with pre-filled values
- Update the commit message if needed
- Click Publish to update the remote file
The system automatically detects if the file already exists and updates it, or creates a new file if it doesn't exist.
Publishing to Feature Branches for CI/CD
You can publish configurations to non-main branches (e.g., feature branches, develop, staging) for CI/CD and testing purposes:
Why use feature branches?
- Testing before merge: Test your configuration changes in a feature branch before merging to main
- CI/CD integration: Your CI/CD pipeline can import and test configurations from feature branches
- Safe experimentation: Make changes without affecting the main branch configuration
- Review workflows: Create pull requests and have configurations reviewed before merging
Important limitation:
- Configuration discovery only searches main/master: The global configuration discovery feature only searches the
mainormasterbranches - Feature branches won't appear in discovery: Configurations published to feature branches will not appear in the "Discover" tab search results
- Manual import still works: You can still import configurations from feature branches using:
- Import from GitHub tab: Browse the repository and select the feature branch
- Import from URL tab: Use the raw GitHub URL pointing to the feature branch
Example workflow:
- Create a feature branch:
git checkout -b feature/new-configuration - Publish to feature branch:
- Select your repository
- Choose the feature branch (e.g.,
feature/new-configuration) - Set the file path (e.g.,
lib/Settings/config.json) - Publish the configuration
- Test in CI/CD: Your CI/CD pipeline can import from the feature branch URL
- Review and merge: Create a pull request, review changes, then merge to main
- Publish to main: After merging, publish the configuration to the main branch so it appears in discovery
Raw URL format for feature branches:
https://raw.githubusercontent.com/owner/repo/feature/new-configuration/lib/Settings/config.json
Best practices:
- Use feature branches for development and testing
- Publish to
mainormasterfor production configurations - Document branch naming conventions in your team
- Use descriptive commit messages when publishing to feature branches
Publishing Status
Published configurations display:
- Red 'Published' badge: Indicates the configuration is published to GitHub
- Repository information: Shows the repository, branch, and path in the configuration card
- Update Published action: Available in the actions menu for already-published configurations
Alternative: Manual Upload to GitHub
If you prefer to upload manually:
- Export your configuration (JSON file)
- Create or navigate to your GitHub repository
- Create a directory for configurations (e.g., 'config/')
- Upload your configuration file
- Commit with descriptive message
- Others can now import using your repository URL
Option 2: Upload to GitLab
Similar to GitHub:
- Export configuration
- Navigate to your GitLab project
- Upload to a logical directory
- Commit changes
- Share project URL
Option 3: Host on Your Server
- Export configuration
- Upload to your web server
- Make accessible via HTTPS
- Share the direct URL
- Others can import using 'Import from URL'
Example URL:
https://mysite.com/configs/myapp.openregister.json
Best Practices for Sharing
- Include README: Document what your configuration does
- Version Properly: Use semantic versioning in 'info.version'
- Set Version Requirements: Specify compatible OpenRegister versions
- Test Before Sharing: Verify imports work correctly
- Maintain Documentation: Keep usage instructions updated
- Use Descriptive Names: Make file names self-explanatory
- Regular Updates: Keep configurations current with your app
Programmatic Configuration Import for Apps
Apps can programmatically import their configurations using the ConfigurationService without needing to manually create Configuration entities. This is useful for:
- App initialization and setup
- Automatic configuration deployment
- Version-based configuration updates
- Bundling configurations with app releases
OpenRegister provides two methods for importing configurations:
Method 1: Import from File Path (Recommended)
The importFromFilePath method is the recommended approach when your configuration is stored in a JSON file. OpenRegister handles all file reading and parsing:
// Get the configuration service
$configurationService = $this->container->get('OCA\OpenRegister\Service\ConfigurationService');
// Import from file path (relative to Nextcloud root)
$result = $configurationService->importFromFilePath(
appId: 'myapp',
filePath: 'apps-extra/myapp/lib/Settings/myapp_config.json',
version: '1.0.0',
force: false
);
Benefits:
- OpenRegister handles file reading and JSON parsing
- Automatically sets sourceUrl for cron job tracking
- Ensures configuration uniqueness by sourceUrl
- Enables automatic update checking by the cron job
Method 2: Import from Data Array
The importFromApp method is for when you already have configuration data in memory:
// Get the configuration service
$configurationService = $this->container->get('OCA\OpenRegister\Service\ConfigurationService');
// Load your configuration data (from JSON file, array, etc.)
$configData = json_decode(file_get_contents('path/to/config.json'), true);
// Import the configuration
$result = $configurationService->importFromApp(
appId: 'myapp', // Your app ID
data: $configData, // Configuration data array
version: '1.0.0', // Version string
force: false // Force import even if version is not newer
);
// Result contains imported entities
// $result['registers'] - Array of imported Register entities
// $result['schemas'] - Array of imported Schema entities
// $result['objects'] - Array of imported Object entities
How It Works
Both import methods automatically:
- Finds or Creates Configuration Entity:
- First checks by sourceUrl (if provided) to ensure uniqueness
- Falls back to checking by app ID if no sourceUrl match
- Creates a new Configuration entity if none exists
- Handles Version Checking: Compares versions and skips import if the same or older version is already installed (unless force=true).
- Tracks Imported Entities: Associates all imported registers, schemas, and objects with the Configuration entity.
- Updates Configuration: Merges new entity IDs with existing ones on subsequent imports, and updates metadata from the import data.
Example: App Installation Hook
Use this in your app's installation or upgrade hooks:
namespace OCA\MyApp\Migration;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
use Psr\Container\ContainerInterface;
class InstallConfiguration implements IRepairStep {
private ContainerInterface $container;
public function __construct(ContainerInterface $container) {
$this->container = $container;
}
public function getName(): string {
return 'Install MyApp configuration';
}
public function run(IOutput $output): void {
try {
// Get configuration service
$configService = $this->container->get(
'OCA\OpenRegister\Service\ConfigurationService'
);
// Load configuration from bundled JSON file
$configPath = __DIR__ . '/../Settings/configuration.json';
$configData = json_decode(file_get_contents($configPath), true);
// Import configuration
$result = $configService->importFromApp(
appId: 'myapp',
data: $configData,
version: '1.0.0',
force: false
);
$output->info(sprintf(
'Configuration imported: %d registers, %d schemas, %d objects',
count($result['registers']),
count($result['schemas']),
count($result['objects'])
));
} catch (\Exception $e) {
$output->warning('Failed to import configuration: ' . $e->getMessage());
}
}
}
Example: Version-Based Updates
Update configurations only when app version increases:
// In your app's upgrade logic
$appManager = \OC::$server->getAppManager();
$currentVersion = $appManager->getAppVersion('myapp');
$configService = $this->container->get('OCA\OpenRegister\Service\ConfigurationService');
// Check if update is needed
$storedVersion = $configService->getConfiguredAppVersion('myapp');
if ($storedVersion === null || version_compare($currentVersion, $storedVersion, '>')) {
// Load updated configuration
$configData = $this->loadConfiguration();
// Import with app version
$result = $configService->importFromApp(
appId: 'myapp',
data: $configData,
version: $currentVersion,
force: false
);
// Configuration is now at the current app version
}
Configuration Data Format
Your configuration data should follow the OpenAPI 3.0 specification with OpenRegister-specific metadata stored in the x-openregister extension field following the OpenAPI Extensions specification.
{
"openapi": "3.0.0",
"info": {
"title": "MyApp Configuration",
"description": "Default configuration for MyApp",
"version": "1.0.0"
},
"x-openregister": {
"type": "app",
"app": "myapp",
"sourceType": "local",
"sourceUrl": "apps-extra/myapp/lib/Settings/myapp_config.json",
"github": {
"repo": null,
"branch": null,
"path": null
}
},
"components": {
"registers": {
"myregister": {
"title": "My Register",
"slug": "myregister",
"description": "Application data register",
"version": "1.0.0",
"schemas": ["myschema"]
}
},
"schemas": {
"myschema": {
"title": "My Schema",
"slug": "myschema",
"version": "1.0.0",
"type": "object",
"properties": {
"name": {
"type": "string",
"title": "Name"
},
"description": {
"type": "string",
"title": "Description"
}
},
"required": ["name"]
}
}
}
}
x-openregister Extension
The x-openregister extension contains OpenRegister-specific metadata following the OpenAPI Extensions specification. This extension is used to store configuration properties that are not part of the standard OpenAPI specification.
Standard OAS Properties (in info section):
title: Configuration titledescription: Configuration descriptionversion: Configuration version
OpenRegister-specific Properties (in x-openregister extension):
type: Type of configuration (e.g., 'app', 'imported', 'manual')app: Application identifiersourceType: Source type ('local', 'github', 'gitlab', 'url', 'manual')sourceUrl: File path or URL to configuration source (relative to Nextcloud root for local files)github: Object containing GitHub-specific properties:repo: GitHub repository (format: 'owner/repo')branch: GitHub branch name (e.g., 'main', 'develop')path: Path within GitHub repository (e.g., 'configs/schema.json')
Properties excluded from export/import:
The following internal properties are managed automatically by the system and are NOT included in configuration exports or processed during imports:
System-managed metadata:
id: Internal database IDuuid: Internal UUIDcreated: Creation timestampupdated: Last update timestamplastChecked: Last version check timestampremoteVersion: Remote version (auto-detected)localVersion: Local version (auto-updated)
Instance-specific settings:
autoUpdate: Whether to automatically update (instance-specific preference)notificationGroups: Groups to notify on updates (instance-specific)owner: Owner user ID (instance-specific)organisation: Organisation UUID (instance-specific, may not exist in target instance)
Entity references (tracked automatically during import):
registers: Array of register IDs (built from components.registers)schemas: Array of schema IDs (built from components.schemas)objects: Array of object IDs (built from components.objects)views: Array of view IDs (tracked automatically)agents: Array of agent IDs (tracked automatically)sources: Array of source IDs (tracked automatically)applications: Array of application IDs (tracked automatically)
Minimal Configuration Example:
For simple use cases, you only need to include the essential fields:
{
"openapi": "3.0.0",
"info": {
"title": "MyApp Configuration",
"version": "1.0.0"
},
"x-openregister": {
"type": "app",
"app": "myapp",
"version": "1.0.0"
},
"components": {
"registers": {},
"schemas": {}
}
}
Best Practices
Configuration Files
- Store configuration in
Settings/orConfig/directory within your app - Use semantic versioning for your configuration
- Include metadata (appId, version, title, description) in the JSON
Version Management
- Set version to match your app version
- Increment configuration version with app updates
- Use
force: falseto respect version checks - Only use
force: trueduring development or explicit reinstalls
Error Handling
- Wrap imports in try-catch blocks
- Log errors appropriately
- Provide meaningful error messages to admins
- Consider fallback behavior if import fails
Testing
- Test configuration imports in development environment first
- Verify all registers, schemas, and objects are created correctly
- Test upgrade scenarios (version updates)
- Test fresh install scenarios
Configuration API
List Configurations
GET /index.php/apps/openregister/api/configurations
Get Single Configuration
GET /index.php/apps/openregister/api/configurations/{id}
Create Configuration
POST /index.php/apps/openregister/api/configurations
Content-Type: application/json
{
"title": "My Application",
"description": "Core application configuration",
"type": "application",
"registers": [1, 2, 3],
"schemas": [4, 5, 6]
}
Update Configuration
PUT /index.php/apps/openregister/api/configurations/{id}
Content-Type: application/json
{
"title": "Updated Application",
"description": "Updated description",
"registers": [1, 2, 3, 7],
"schemas": [4, 5, 6, 8]
}
Delete Configuration
DELETE /index.php/apps/openregister/api/configurations/{id}
Data Structure
Configuration Entity
{
id: string
title: string
description: string | null
type: string
owner: string
registers: number[] // Array of register IDs
schemas: number[] // Array of schema IDs
objects: number[] // Array of object IDs (optional)
created: string // ISO 8601 timestamp
updated: string // ISO 8601 timestamp
}
Database Schema
The configuration is stored in the 'oc_openregister_configurations' table with the following fields:
- 'id': Primary key (integer)
- 'title': Configuration name (string)
- 'description': Detailed description (text, nullable)
- 'type': Configuration type (string)
- 'app': Owner/app identifier (string)
- 'version': Configuration version (string)
- 'registers': JSON array of register IDs
- 'schemas': JSON array of schema IDs
- 'objects': JSON array of object IDs
- 'created': Creation timestamp (datetime)
- 'updated': Last update timestamp (datetime)
Best Practices
Naming Conventions
- Use descriptive titles that clearly indicate the configuration's purpose
- Include the application or tenant name in the title when applicable
- Use consistent type values across your system (e.g., always use 'application', not 'app' or 'Application')
Organization
- Create configurations for logical groupings of functionality
- Keep configurations focused - don't mix unrelated registers and schemas
- Use configurations to enforce multi-tenancy boundaries
- Document the purpose of each configuration in the description field
Version Management
- The system automatically increments the patch version on each update
- Major and minor version changes should be managed manually when needed
- Export configurations before making major structural changes
Multi-Tenancy
- Create separate configurations for each tenant
- Never share registers or schemas between tenant configurations
- Use the owner/app field to identify the tenant
- Export/import configurations to provision new tenants
Troubleshooting
Cannot Save Configuration
Problem: Save button is disabled
Solution: Ensure both title and type fields are filled in. These are required fields.
Registers/Schemas Not Showing in Dropdown
Problem: No items appear in the register or schema selector
Solution:
- Ensure you have created registers and schemas in the system
- Refresh the page to reload the data
- Check that you have the necessary permissions to view registers and schemas
Changes Not Persisting
Problem: Selected registers or schemas are not saved
Solution:
- Verify that you clicked the Save button (not just closed the modal)
- Check browser console for any API errors
- Ensure you have write permissions for configurations
- Try refreshing the page and editing again
Import Fails
Problem: Configuration import returns an error
Solution:
- Verify the JSON file format is correct
- Ensure referenced registers and schemas exist or will be created
- Check for ID conflicts if importing into a system with existing data
- Review server logs for detailed error messages
Related Features
- Registers - Learn about register management
- Schemas - Learn about schema definitions
- Objects - Learn about object management
- Import/Export - Detailed import/export documentation
- Multi-Tenancy - Multi-tenancy implementation details
Configuration Management System
The Configuration Management System provides advanced features for managing configurations from remote sources, tracking versions, and keeping configurations synchronized.
Overview
The configuration management system allows you to:
- Link configurations to remote sources (GitHub, GitLab, URL)
- Track local and remote versions automatically
- Preview changes before importing
- Selectively import only the changes you want
- Set up automatic updates when new versions are detected
- Receive Nextcloud notifications when updates are available
- Push local configurations to GitHub repositories
Source Types
Configurations can be managed from different source types:
Local Source
A locally managed configuration that is not synchronized with any remote source. This is the default type and is suitable for:
- Custom configurations specific to your installation
- Configurations used for exporting to other systems
- Development and testing purposes
GitHub Source
Configuration synchronized with a GitHub repository. Requires:
- A GitHub Personal Access Token (configured in user settings)
- Repository name in format 'owner/repo'
- Branch name (e.g., 'main', 'develop')
- File path within the repository
GitLab Source
Configuration synchronized with a GitLab repository. Works similarly to GitHub with GitLab-specific authentication.
URL Source
Configuration fetched from any publicly accessible URL. The URL should point to a raw JSON or YAML configuration file.
Version Tracking
The system tracks two version numbers for each configuration:
Local Version
The version currently installed in your system. This is updated automatically when you:
- Import a configuration
- Make manual changes to managed entities
- Apply updates from a remote source
Remote Version
The latest version available from the remote source. The system:
- Checks this automatically via the cron job
- Compares it with the local version using semantic versioning
- Shows an update notification if a newer version is available
Previewing Configuration Changes
Before importing or updating a configuration, you can preview all changes that will be applied:
Preview Modal Features
The preview modal shows:
-
Summary Information
- Configuration title and description
- Local and remote version numbers
- Total number of changes
-
Change Details by Entity Type
- Registers: What will be created or updated
- Schemas: What will be created or updated
- Objects: What will be created or updated
-
Action Indicators
- Create: New entity will be created
- Update: Existing entity will be modified
- Skip: No changes detected
-
Version Comparison
- Current version of each entity
- Proposed version from remote configuration
-
Field-Level Differences
- Shows exactly which fields will change
- Displays old and new values
- Highlights additions and deletions
Selective Import
You can choose which changes to apply:
- Select All button: Selects all proposed changes
- Deselect All button: Clears all selections
- Individual Selection: Check/uncheck specific entities
- Import Selected button: Applies only the selected changes
Auto-Update Functionality
Configurations can be set to automatically update when new versions are detected:
Enabling Auto-Update
- Edit the configuration
- Navigate to the Management tab
- Check Enable Auto-Update
- Save the configuration
When auto-update is enabled:
- The cron job checks for updates hourly
- If a newer version is found, it is automatically imported
- All changes are applied without requiring user approval
- No preview or selection is performed
- Admins are notified after the update completes
Important: Use auto-update only for trusted sources where you want all changes applied automatically.
Notification System
The system can notify users when configuration updates are available:
Notification Groups
Configure which groups receive notifications:
- Admin Group (always included): System administrators
- Custom Groups: Add any Nextcloud groups
Notification Behavior
- Notifications are sent when a newer remote version is detected
- Auto-update configurations bypass the notification (update happens automatically)
- Clicking a notification takes you to the configuration preview
- Notifications are dismissed once the update is applied
Managed Entities
Entities (Registers, Schemas, Objects) that are created from a configuration are marked as managed:
Restrictions on Managed Entities
- Cannot be edited directly through their detail pages
- Edit buttons are disabled in the UI
- API attempts to modify them return an error
- Only the configuration that manages them can update them
Identifying Managed Entities
Managed entities display a pill badge showing:
- Configuration Name: Which configuration manages the entity
- Version: The current version from that configuration
Entities without a configuration show a Manual badge, indicating they can be edited freely.
GitHub Integration
The system provides deep integration with GitHub for configuration management:
Push to GitHub
Export your configuration directly to a GitHub repository:
- Navigate to the configuration detail page
- Click Actions → Push to GitHub
- The configuration is committed to the configured repository
Requirements:
- GitHub Personal Access Token set in user settings
- Repository, branch, and path configured in the configuration
- Write access to the target repository
Create Pull Request
Create a pull request for your configuration changes:
- Make changes to a configuration
- Click Actions → Create Pull Request
- A new PR is created in the configured repository
This allows for review workflows before changes are merged.
Configuration Management Tab
The configuration edit modal includes a Management tab with these fields:
Source Settings
- Source Type: Choose from Local, GitHub, GitLab, or URL
- Source URL: The URL to the remote configuration file (for remote types)
Version Settings
- Local Version: The currently installed version (editable)
- Remote Version: Latest version from remote source (read-only, auto-detected)
Update Settings
- Enable Auto-Update: Checkbox to enable automatic updates
- Notification Groups: Select which groups receive update notifications
GitHub Settings (when Source Type is GitHub)
- GitHub Repository: Format 'owner/repo'
- GitHub Branch: The branch to use (default: 'main')
- GitHub Path: Path to the configuration file within the repository
API Endpoints
Check Remote Version
GET /index.php/apps/openregister/api/configurations/{id}/check-version
Checks the remote source for a newer version and updates the 'remoteVersion' field.
Response:
{
'localVersion': '1.0.0',
'remoteVersion': '1.1.0',
'hasUpdate': true,
'lastChecked': '2025-01-15T10:30:00Z'
}
Preview Configuration Changes
GET /index.php/apps/openregister/api/configurations/{id}/preview
Generates a preview of changes that would be applied if the remote configuration were imported.
Response:
{
'metadata': {
'localVersion': '1.0.0',
'remoteVersion': '1.1.0',
'totalChanges': 5
},
'registers': [
{
'slug': 'myregister',
'title': 'My Register',
'action': 'update',
'current': { 'version': '1.0.0' },
'proposed': { 'version': '1.1.0' },
'changes': [
{
'field': 'description',
'current': 'Old description',
'proposed': 'New description'
}
]
}
],
'schemas': [...],
'objects': [...]
}
Import with Selection
POST /index.php/apps/openregister/api/configurations/{id}/import
Content-Type: application/json
{
'selection': {
'registers': ['register1', 'register2'],
'schemas': ['schema1'],
'objects': ['register1:schema1:object1']
}
}
Imports only the selected entities from the remote configuration.
Response:
{
'registersCount': 2,
'schemasCount': 1,
'objectsCount': 1,
'localVersion': '1.1.0'
}
Export Configuration
GET /index.php/apps/openregister/api/configurations/{id}/export?format=json
Exports the configuration with all managed entities following the OpenAPI 3.0 specification with OpenRegister metadata in the x-openregister extension.
Query Parameters:
- 'format': 'json' or 'yaml'
- 'includeObjects': 'true' or 'false' (default: false)
Response Structure:
{
"openapi": "3.0.0",
"info": {
"title": "Configuration Title",
"description": "Configuration Description",
"version": "1.0.0"
},
"x-openregister": {
"title": "Configuration Title",
"description": "Configuration Description",
"type": "app",
"app": "myapp",
"version": "1.0.0",
"sourceType": "local",
"sourceUrl": null,
"github": {
"repo": null,
"branch": null,
"path": null
}
},
"components": {
"registers": {},
"schemas": {},
"objects": []
}
}
Note: The exported configuration follows the OpenAPI Extensions specification by storing OpenRegister-specific metadata in the x-openregister extension field.
Excluded properties:
- From Configuration: System-managed metadata (id, uuid, created, updated, lastChecked, remoteVersion, localVersion), instance-specific settings (autoUpdate, notificationGroups, owner, organisation), and entity reference arrays (registers, schemas, objects, views, agents, sources, applications)
- From Registers/Schemas/Objects: id, uuid, organisation (all instance-specific)
- Entity references are tracked automatically during import from the
componentssection
Background Jobs
The system includes a cron job that runs hourly (configurable):
Configuration Check Job
Purpose: Check all remote configurations for updates
Behavior:
- Loads all configurations with remote sources
- For each configuration, fetches the remote file
- Compares remote version with local version
- If auto-update is enabled: Automatically imports the new version
- If auto-update is disabled: Sends notification to configured groups
- Updates the 'lastChecked' timestamp
Configuration:
Set the check interval in Nextcloud admin settings (in seconds, 0 to disable):
'openregister.configuration.check_interval' => 3600 // 1 hour
Best Practices
Version Management
- Use semantic versioning (MAJOR.MINOR.PATCH)
- Increment PATCH for bug fixes and minor changes
- Increment MINOR for new features (backward compatible)
- Increment MAJOR for breaking changes
- Always update the version in your remote configuration when making changes
Source Selection
- Use Local for configurations you manage entirely within Nextcloud
- Use GitHub when collaborating with others or tracking changes in version control
- Use URL for read-only configurations from external sources
- Use GitLab if your organization uses GitLab
Auto-Update Usage
- Enable for trusted, stable configuration sources
- Disable for production systems where you want to review changes first
- Test configurations in a staging environment before enabling auto-update in production
- Always keep backups before enabling auto-update
Notification Strategy
- Add your DevOps team to notification groups for all configurations
- Create specific groups for different configuration types
- Review and apply updates promptly to stay current with remote sources
Troubleshooting
Remote Version Not Updating
Problem: The remote version field shows '-' or an old version
Solution:
- Click Actions → Check Version to manually trigger a check
- Verify the source URL is correct and accessible
- Check that the remote file has a 'version' or 'info.version' field
- Review server logs for connection errors
Preview Shows No Changes
Problem: Preview modal shows no changes even though you expect updates
Solution:
- Verify the remote version is actually newer than the local version
- Check that entity slugs match between local and remote configurations
- Ensure the remote configuration uses the same structure
Import Fails with Selection
Problem: Importing selected entities returns an error
Solution:
- Check that all referenced schemas and registers exist
- Verify you have write permissions for the configuration
- Review the preview for any validation errors
- Check server logs for detailed error messages
Managed Entity Cannot Be Edited
Problem: Edit button is disabled on a schema or register
Solution:
- This is expected behavior for managed entities
- To edit, modify the source configuration and re-import
- Alternatively, remove the entity from the configuration to make it editable
- For local configurations, edit through the configuration itself
LLM Configuration Settings
The LLM Configuration page displays information about your AI stack configuration, including embedding providers, chat providers, and database status.
Database Status Tile
The database status tile shows your database type, version, and vector search capability to help you optimize performance.
What It Shows
The tile displays:
- Database Type: MariaDB, MySQL, PostgreSQL, or SQLite
- Database Version: Current version number
- Vector Support: Whether native vector operations are supported
- Recommended Plugin: Suggests pgvector for PostgreSQL
- Performance Note: Guidance on optimization
Database Detection
The system automatically detects:
- MariaDB: Identified by 'MariaDB' string in version
- MySQL: Identified when version doesn't contain 'MariaDB'
- PostgreSQL: Detected via platform name and extension queries
- SQLite: Detected via platform name
Vector Support Check
- MariaDB/MySQL: No native vector support (always shows warning)
- PostgreSQL: Checks for
pgvectorextension installation - SQLite: No vector support (not recommended for production)
Performance Recommendations
| Database | Vector Support | Performance Note |
|---|---|---|
| MariaDB | ✗ | PHP similarity (slow) → migrate to PostgreSQL |
| MySQL | ✗ | PHP similarity (slow) → migrate to PostgreSQL |
| PostgreSQL (no pgvector) | ✗ | Install: CREATE EXTENSION vector; |
| PostgreSQL (with pgvector) | ✓ | Optimal: Database-level vector ops |
| SQLite | ✗ | Not recommended for production |