Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.
Closed
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
9 changes: 6 additions & 3 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@ Free and open source under the EUPL-1.2 license.

**Belangrijkste functies**

- **Vue 2 + Pinia frontend** — Moderne reactieve UI met state management
- **Bestuursorganen en vergaderingen** — Volledig beheer van bestuursorganen, deelnemers, agenda's en vergaderverslagen
- **Besluitvorming** — Gestructureerde ondersteuning voor moties, amendementen, stemrondes en besluiten
- **OpenRegister-integratie** — Ingebouwde ondersteuning voor de OpenRegister-datalaag
- **Beheerdersinstellingen** — Voorgeconfigureerde instellingenpagina met versie-informatie
- **NL Design System klaar** — CSS-variabelen, WCAG AA, overheidsthema
- **Volledige kwaliteitspipeline** — PHPCS, PHPMD, Psalm, PHPStan, ESLint, Stylelint

Vrij en open source onder de EUPL-1.2-licentie.

**Ondersteuning:** Voor ondersteuning, neem contact op via support@conduction.nl.
]]></description>
<version>0.1.0</version>
<licence>agpl</licence>
<licence>eupl</licence>
<author mail="info@conduction.nl" homepage="https://www.conduction.nl/">Conduction</author>
<namespace>Decidesk</namespace>
<documentation>
Expand Down Expand Up @@ -66,6 +66,9 @@ Vrij en open source onder de EUPL-1.2-licentie.
</navigations>

<repair-steps>
<install>
<step>OCA\Decidesk\Repair\InitializeSettings</step>
</install>
<post-migration>
<step>OCA\Decidesk\Repair\InitializeSettings</step>
</post-migration>
Expand Down
14 changes: 12 additions & 2 deletions lib/Controller/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
* @version GIT: <git-id>
*
* @link https://conduction.nl
*
* @spec openspec/changes/p1-crud-operations/tasks.md#task-2.4
*/

declare(strict_types=1);
Expand All @@ -23,15 +25,19 @@

use OCA\Decidesk\AppInfo\Application;
use OCA\Decidesk\Service\SettingsService;
use OCA\Decidesk\Settings\AdminSettings;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\AuthorizedAdminSetting;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IGroupManager;
use OCP\IRequest;
use OCP\IUserSession;

/**
* Controller for managing Decidesk application settings.
*
* @spec openspec/changes/p1-crud-operations/tasks.md#task-2.4
*/
class SettingsController extends Controller
{
Expand Down Expand Up @@ -73,8 +79,8 @@ private function requireAdmin(): ?JSONResponse
* Retrieve all current settings.
*
* @NoAdminRequired
*
* @spec openspec/changes/p1-dashboard-and-navigation/tasks.md#task-2.1
* @spec openspec/changes/p1-dashboard-and-navigation/tasks.md#task-2.1
* @spec openspec/changes/p1-crud-operations/tasks.md#task-2.4
*
* @return JSONResponse
*/
Expand All @@ -89,9 +95,11 @@ public function index(): JSONResponse
* Update settings with provided data.
*
* @spec openspec/changes/p1-dashboard-and-navigation/tasks.md#task-2.2
* @spec openspec/changes/p1-crud-operations/tasks.md#task-2.4
*
* @return JSONResponse
*/
#[AuthorizedAdminSetting(AdminSettings::class)]
public function create(): JSONResponse
{
$denied = $this->requireAdmin();
Expand All @@ -118,9 +126,11 @@ public function create(): JSONResponse
*
* @spec openspec/changes/p1-dashboard-and-navigation/tasks.md#task-2.1
* @spec openspec/changes/p1-dashboard-and-navigation/tasks.md#task-2.2
* @spec openspec/changes/p1-crud-operations/tasks.md#task-2.4
*
* @return JSONResponse
*/
#[AuthorizedAdminSetting(AdminSettings::class)]
public function load(): JSONResponse
{
$denied = $this->requireAdmin();
Expand Down
6 changes: 3 additions & 3 deletions lib/Listener/DeepLinkRegistrationListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*
* @link https://conduction.nl
*
* @spec openspec/changes/p1-schemas-and-data-model/tasks.md#task-1
* @spec openspec/changes/p1-crud-operations/tasks.md#task-2.6
*/

declare(strict_types=1);
Expand All @@ -35,7 +35,7 @@
*
* @implements IEventListener<Event>
*
* @spec openspec/changes/p1-schemas-and-data-model/tasks.md#task-1
* @spec openspec/changes/p1-crud-operations/tasks.md#task-2.6
*/
class DeepLinkRegistrationListener implements IEventListener
{
Expand Down Expand Up @@ -71,7 +71,7 @@ class DeepLinkRegistrationListener implements IEventListener
*
* @return void
*
* @spec openspec/changes/p1-schemas-and-data-model/tasks.md#task-1
* @spec openspec/changes/p1-crud-operations/tasks.md#task-2.6
*/
public function handle(Event $event): void
{
Expand Down
4 changes: 2 additions & 2 deletions lib/Repair/InitializeSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*
* @link https://conduction.nl
*
* @spec openspec/changes/p1-schemas-and-data-model/tasks.md#task-3
* @spec openspec/changes/p1-crud-operations/tasks.md#task-2.1
*/

declare(strict_types=1);
Expand All @@ -31,7 +31,7 @@
/**
* Repair step that initializes Decidesk configuration via SettingsService.
*
* @spec openspec/changes/p1-schemas-and-data-model/tasks.md#task-3
* @spec openspec/changes/p1-crud-operations/tasks.md#task-2.1
*/
class InitializeSettings implements IRepairStep
{
Expand Down
4 changes: 4 additions & 0 deletions lib/Service/SettingsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
* @version GIT: <git-id>
*
* @link https://conduction.nl
*
* @spec openspec/changes/p1-crud-operations/tasks.md#task-2.3
*/

declare(strict_types=1);
Expand All @@ -31,6 +33,8 @@

/**
* Service for managing Decidesk application configuration and settings.
*
* @spec openspec/changes/p1-crud-operations/tasks.md#task-2.3
*/
class SettingsService
{
Expand Down
26 changes: 24 additions & 2 deletions lib/Settings/AdminSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@
use OCA\Decidesk\AppInfo\Application;
use OCP\App\IAppManager;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\Settings\ISettings;
use OCP\Settings\IDelegatedSettings;

/**
* Provides the admin settings form for the Decidesk application.
*/
class AdminSettings implements ISettings
class AdminSettings implements IDelegatedSettings
{
/**
* Constructor.
Expand Down Expand Up @@ -76,4 +76,26 @@ public function getPriority(): int
{
return 10;
}//end getPriority()

/**
* Get the sub-name for differentiating settings within a section.
*
* @return string|null
*/
public function getName(): ?string
{
return null;
}//end getName()

/**
* Get authorized app config keys that delegated admins may modify.
*
* @return array<string, array<string>>
*/
public function getAuthorizedAppConfig(): array
{
return [
Application::APP_ID => ['/register/'],
];
}//end getAuthorizedAppConfig()
}//end class
77 changes: 76 additions & 1 deletion lib/Settings/decidesk_register.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,28 @@
"votingDefault": "for-against-abstain",
"termStart": "2024-01-01T00:00:00Z",
"termEnd": "2027-12-31T23:59:59Z"
},
{
"@self": {
"register": "decidesk",
"schema": "GovernanceBody",
"slug": "directieteam-gemeente-utrecht"
},
"name": "Directieteam Gemeente Utrecht",
"bodyType": "operational",
"domain": "municipality",
"votingDefault": "show-of-hands"
},
{
"@self": {
"register": "decidesk",
"schema": "GovernanceBody",
"slug": "auditcommissie-provincie-nh"
},
"name": "Auditcommissie Provincie Noord-Holland",
"bodyType": "legislative",
"domain": "province",
"votingDefault": "for-against-abstain"
}
]
},
Expand Down Expand Up @@ -264,6 +286,21 @@
"meetingMode": "in-person",
"lifecycle": "draft",
"quorumRequired": 13
},
{
"@self": {
"register": "decidesk",
"schema": "Meeting",
"slug": "ledenvergadering-veh-voorjaar-2025"
},
"title": "Algemene Ledenvergadering VEH — Voorjaar 2025",
"meetingType": "public hearing",
"scheduledDate": "2025-06-18T13:00:00Z",
"endDate": "2025-06-18T17:00:00Z",
"location": "World Forum Den Haag",
"meetingMode": "in-person",
"lifecycle": "scheduled",
"quorumRequired": 50
}
]
},
Expand Down Expand Up @@ -387,6 +424,19 @@
"email": "p.vandam@example.waterschap.nl",
"joinedAt": "2024-01-15T00:00:00Z",
"votingWeight": 0
},
{
"@self": {
"register": "decidesk",
"schema": "Participant",
"slug": "participant-ans-rutten"
},
"displayName": "Ans Rutten",
"role": "vice-chair",
"party": "CDA",
"email": "a.rutten@example.gemeente.nl",
"joinedAt": "2022-03-30T00:00:00Z",
"votingWeight": 1
}
]
},
Expand Down Expand Up @@ -493,6 +543,31 @@
"orderNumber": 99,
"estimatedDuration": 15,
"isRecurring": true
},
{
"@self": {
"register": "decidesk",
"schema": "AgendaItem",
"slug": "agendaitem-notulen-2024-12-18"
},
"title": "Vaststellen notulen vergadering 18 december 2024",
"itemType": "decision",
"orderNumber": 2,
"estimatedDuration": 10,
"isRecurring": true
},
{
"@self": {
"register": "decidesk",
"schema": "AgendaItem",
"slug": "agendaitem-kadernota-2026"
},
"title": "Kadernota begroting 2026",
"itemType": "discussion",
"orderNumber": 4,
"estimatedDuration": 60,
"description": "Eerste bespreking van de financiële kaders voor begrotingsjaar 2026",
"isRecurring": false
}
]
},
Expand Down Expand Up @@ -976,7 +1051,7 @@
"active": true,
"hardDelete": false,
"searchable": true,
"mailEnabled": true,
"mailEnabled": false,
"x-mail-security-audit": "mailEnabled activates inbound email ingestion. Before production: verify OpenRegister sanitizes HTML/headers, validate sender identity, and ensure Decision views never use v-html for mail-sourced content. Tracked in issue #6."
},
"required": [
Expand Down
4 changes: 4 additions & 0 deletions openspec/changes/p1-crud-operations/design.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
status: pr-created
---

## Context

Decidesk is a Nextcloud app using the **thin-client** pattern: the app owns no database tables. All domain data is stored as JSON objects in OpenRegister. The frontend talks to the OpenRegister API directly via Pinia object stores. The backend is minimal — only a `SettingsController` for configuration and a repair step that imports the register schema.
Expand Down
Loading
Loading