Architecture Overview¶
This document describes the technical architecture of FormVox.
System Design¶
File-Based Architecture¶
FormVox uses a unique file-based approach:
┌─────────────────────────────────────────────────┐
│ Nextcloud │
├─────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────────────┐ │
│ │ FormVox │ │ Nextcloud Files │ │
│ │ App │◄──►│ (.fvform files) │ │
│ └──────────────┘ └──────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ Vue.js │ │
│ │ Frontend │ │
│ └──────────────┘ │
└─────────────────────────────────────────────────┘
Key Principles¶
- No Database Tables - All data stored in files
- Native Integration - Uses Nextcloud's file system
- Portability - Forms can be copied, moved, shared like any file
- Encryption Compatible - Works with server-side and E2E encryption
Components¶
Backend (PHP)¶
Located in lib/:
lib/
├── AppInfo/
│ └── Application.php # App bootstrap
├── Controller/
│ ├── PageController.php # Main page routes
│ ├── FormController.php # Form CRUD operations
│ └── PublicController.php # Public form access
├── Service/
│ └── FormService.php # Business logic
├── Migration/
│ └── RegisterMimeType.php # MIME type registration
├── Settings/
│ ├── AdminSettings.php # Admin panel
│ └── AdminSection.php # Admin navigation
└── BackgroundJob/
└── TelemetryJob.php # Telemetry reporting
Frontend (Vue.js)¶
Located in src/:
src/
├── main.js # App entry point
├── files.js # Files app integration
├── App.vue # Main component
├── views/
│ ├── FormEditor.vue # Form editing
│ ├── FormResults.vue # Results dashboard
│ └── PublicForm.vue # Public submission
├── components/
│ ├── QuestionTypes/ # Question components
│ ├── Settings/ # Settings panels
│ └── Results/ # Results components
└── store/
└── index.js # Vuex store
Build Output¶
Located in js/:
Data Flow¶
Form Creation¶
User clicks "New Form"
│
▼
┌───────────────────┐
│ Frontend creates │
│ form structure │
└───────────────────┘
│
▼
┌───────────────────┐
│ API POST request │
│ to /api/forms │
└───────────────────┘
│
▼
┌───────────────────┐
│ FormService │
│ creates .fvform │
└───────────────────┘
│
▼
┌───────────────────┐
│ File saved via │
│ Nextcloud Files │
└───────────────────┘
Response Submission¶
User submits form
│
▼
┌───────────────────┐
│ Frontend validates│
│ and sends data │
└───────────────────┘
│
▼
┌───────────────────┐
│ API POST request │
│ to /api/submit │
└───────────────────┘
│
▼
┌───────────────────┐
│ FormService │
│ - Acquires lock │
│ - Reads file │
│ - Appends response│
│ - Writes file │
│ - Releases lock │
└───────────────────┘
Concurrent Access Handling¶
FormVox handles multiple simultaneous submissions using file locking:
// Simplified locking mechanism
$lock = $this->lockManager->acquireLock($fileId);
try {
$content = $this->readFile($fileId);
$content['responses'][] = $newResponse;
$this->writeFile($fileId, $content);
} finally {
$lock->release();
}
Lock Types¶
- Exclusive lock - For writes (form editing, response submission)
- Shared lock - For reads (viewing results)
Conflict Resolution¶
- Locks have timeout to prevent deadlocks
- Failed locks retry with exponential backoff
- Users see error message if lock cannot be acquired
File Format¶
See File Format for the complete .fvform JSON schema.
API Architecture¶
REST Endpoints¶
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/forms |
List user's forms |
| POST | /api/forms |
Create new form |
| GET | /api/forms/{id} |
Get form details |
| PUT | /api/forms/{id} |
Update form |
| DELETE | /api/forms/{id} |
Delete form |
| GET | /api/forms/{id}/responses |
Get responses |
| POST | /api/submit/{hash} |
Submit response |
See API Reference for complete documentation.
Security Architecture¶
Authentication¶
- Internal API: Nextcloud session authentication
- Public forms: Hash-based access with optional password
Authorization¶
Request → Middleware → Permission Check → Controller
│
▼
┌───────────────┐
│ File system │
│ permissions │
└───────────────┘
Data Validation¶
- Frontend: Vue.js validation
- Backend: PHP type checking and sanitization
- File: JSON schema validation
Performance Considerations¶
Caching¶
- Form structure: Cached in browser
- File content: Nextcloud file cache
- Results: Calculated on-demand
Scalability¶
| Scenario | Performance |
|---|---|
| Small forms (<100 responses) | Instant |
| Medium forms (100-1000) | Fast |
| Large forms (1000+) | Pagination recommended |
Optimization Tips¶
- Use pagination for large result sets
- Archive old responses periodically
- Enable APCu caching in Nextcloud
Integration Points¶
Nextcloud Integration¶
- Files app - Custom file handler for
.fvform - Sharing - Uses Nextcloud sharing API
- Search - Forms searchable in Unified Search
- Activity - Form events in activity stream
External Integration¶
- REST API for programmatic access
- JSON export for data analysis
- Webhook support (planned)
Development Architecture¶
Build System¶
Technologies¶
- Backend: PHP 8.1+, Nextcloud App Framework
- Frontend: Vue 3, Vuex, Nextcloud Vue components
- Build: Webpack
- Styling: SCSS, Nextcloud styles
Next Steps¶
- File Format - Complete JSON schema
- API Reference - REST API documentation
- Comparison - vs Nextcloud Forms