You've already forked openaccounting-server
forked from cybercinch/openaccounting-server
239 lines
5.3 KiB
Markdown
239 lines
5.3 KiB
Markdown
|
|
# Modular Storage System
|
||
|
|
|
||
|
|
The OpenAccounting server now supports multiple storage backends for file attachments. This allows you to choose between local filesystem storage for simple deployments or cloud storage for production/multi-user environments.
|
||
|
|
|
||
|
|
## Supported Storage Backends
|
||
|
|
|
||
|
|
### 1. Local Filesystem Storage
|
||
|
|
Perfect for self-hosted deployments or development environments.
|
||
|
|
|
||
|
|
**Configuration:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"storage": {
|
||
|
|
"backend": "local",
|
||
|
|
"local": {
|
||
|
|
"root_dir": "./uploads",
|
||
|
|
"base_url": "https://yourapp.com/files"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Environment Variables:**
|
||
|
|
```bash
|
||
|
|
OA_STORAGE_BACKEND=local
|
||
|
|
OA_STORAGE_LOCAL_ROOT_DIR=./uploads
|
||
|
|
OA_STORAGE_LOCAL_BASE_URL=https://yourapp.com/files
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Amazon S3 Storage
|
||
|
|
Reliable cloud storage for production deployments.
|
||
|
|
|
||
|
|
**Configuration:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"storage": {
|
||
|
|
"backend": "s3",
|
||
|
|
"s3": {
|
||
|
|
"region": "us-east-1",
|
||
|
|
"bucket": "my-openaccounting-attachments",
|
||
|
|
"prefix": "attachments",
|
||
|
|
"access_key_id": "AKIA...",
|
||
|
|
"secret_access_key": "...",
|
||
|
|
"endpoint": "",
|
||
|
|
"path_style": false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Environment Variables:**
|
||
|
|
```bash
|
||
|
|
OA_STORAGE_BACKEND=s3
|
||
|
|
OA_STORAGE_S3_REGION=us-east-1
|
||
|
|
OA_STORAGE_S3_BUCKET=my-openaccounting-attachments
|
||
|
|
OA_STORAGE_S3_PREFIX=attachments
|
||
|
|
OA_STORAGE_S3_ACCESS_KEY_ID=AKIA...
|
||
|
|
OA_STORAGE_S3_SECRET_ACCESS_KEY=...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Features:**
|
||
|
|
- Automatic presigned URL generation
|
||
|
|
- Configurable expiry times
|
||
|
|
- Support for S3-compatible services (MinIO, DigitalOcean Spaces)
|
||
|
|
- IAM role support (leave credentials empty to use IAM)
|
||
|
|
|
||
|
|
### 3. Backblaze B2 Storage
|
||
|
|
Cost-effective cloud storage alternative to S3.
|
||
|
|
|
||
|
|
**Configuration:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"storage": {
|
||
|
|
"backend": "b2",
|
||
|
|
"b2": {
|
||
|
|
"account_id": "your-b2-account-id",
|
||
|
|
"application_key": "your-b2-application-key",
|
||
|
|
"bucket": "my-openaccounting-attachments",
|
||
|
|
"prefix": "attachments"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Environment Variables:**
|
||
|
|
```bash
|
||
|
|
OA_STORAGE_BACKEND=b2
|
||
|
|
OA_STORAGE_B2_ACCOUNT_ID=your-b2-account-id
|
||
|
|
OA_STORAGE_B2_APPLICATION_KEY=your-b2-application-key
|
||
|
|
OA_STORAGE_B2_BUCKET=my-openaccounting-attachments
|
||
|
|
OA_STORAGE_B2_PREFIX=attachments
|
||
|
|
```
|
||
|
|
|
||
|
|
## API Endpoints
|
||
|
|
|
||
|
|
The storage system provides both legacy and new endpoints:
|
||
|
|
|
||
|
|
### New Storage-Agnostic Endpoints
|
||
|
|
|
||
|
|
**Upload Attachment:**
|
||
|
|
```
|
||
|
|
POST /api/v1/attachments
|
||
|
|
Content-Type: multipart/form-data
|
||
|
|
|
||
|
|
transactionId: uuid
|
||
|
|
description: string (optional)
|
||
|
|
file: binary data
|
||
|
|
```
|
||
|
|
|
||
|
|
**Get Attachment Metadata:**
|
||
|
|
```
|
||
|
|
GET /api/v1/attachments/{id}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Get Download URL:**
|
||
|
|
```
|
||
|
|
GET /api/v1/attachments/{id}/url
|
||
|
|
```
|
||
|
|
|
||
|
|
**Download File:**
|
||
|
|
```
|
||
|
|
GET /api/v1/attachments/{id}?download=true
|
||
|
|
```
|
||
|
|
|
||
|
|
**Delete Attachment:**
|
||
|
|
```
|
||
|
|
DELETE /api/v1/attachments/{id}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Legacy Endpoints (Still Supported)
|
||
|
|
The original transaction-scoped endpoints remain available for backward compatibility:
|
||
|
|
- `GET/POST /api/v1/orgs/{orgId}/transactions/{transactionId}/attachments`
|
||
|
|
|
||
|
|
## Security Features
|
||
|
|
|
||
|
|
- **File type validation** - Only allowed MIME types are accepted
|
||
|
|
- **File size limits** - Configurable maximum file size (default 10MB)
|
||
|
|
- **Path traversal protection** - Prevents directory traversal attacks
|
||
|
|
- **Access control** - Files are linked to users and organizations
|
||
|
|
- **Presigned URLs** - Time-limited access for cloud storage
|
||
|
|
|
||
|
|
## File Organization
|
||
|
|
|
||
|
|
Files are automatically organized by date:
|
||
|
|
```
|
||
|
|
uploads/
|
||
|
|
├── 2025/
|
||
|
|
│ ├── 01/
|
||
|
|
│ │ ├── 15/
|
||
|
|
│ │ │ ├── uuid1.pdf
|
||
|
|
│ │ │ └── uuid2.png
|
||
|
|
│ │ └── 16/
|
||
|
|
│ │ └── uuid3.jpg
|
||
|
|
```
|
||
|
|
|
||
|
|
## Configuration Examples
|
||
|
|
|
||
|
|
### Development (Local Storage)
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"storage": {
|
||
|
|
"backend": "local",
|
||
|
|
"local": {
|
||
|
|
"root_dir": "./dev-uploads"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Production (S3 with IAM)
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"storage": {
|
||
|
|
"backend": "s3",
|
||
|
|
"s3": {
|
||
|
|
"region": "us-west-2",
|
||
|
|
"bucket": "prod-openaccounting-files",
|
||
|
|
"prefix": "attachments"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Cost-Optimized (Backblaze B2)
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"storage": {
|
||
|
|
"backend": "b2",
|
||
|
|
"b2": {
|
||
|
|
"account_id": "${B2_ACCOUNT_ID}",
|
||
|
|
"application_key": "${B2_APP_KEY}",
|
||
|
|
"bucket": "openaccounting-prod"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Migration Between Storage Backends
|
||
|
|
|
||
|
|
When changing storage backends, existing attachments will remain in the old storage location. The database records contain the storage path, so files can be accessed until migrated.
|
||
|
|
|
||
|
|
To migrate:
|
||
|
|
1. Update configuration to new backend
|
||
|
|
2. Restart server
|
||
|
|
3. New uploads will use the new backend
|
||
|
|
4. Optional: Run migration script to move existing files
|
||
|
|
|
||
|
|
## Environment-Specific Considerations
|
||
|
|
|
||
|
|
### Self-Hosted
|
||
|
|
- Use local storage for simplicity
|
||
|
|
- Ensure backup strategy includes upload directory
|
||
|
|
- Consider disk space management
|
||
|
|
|
||
|
|
### Cloud Deployment
|
||
|
|
- Use S3 or B2 for reliability and scalability
|
||
|
|
- Configure proper IAM policies
|
||
|
|
- Enable versioning and lifecycle policies
|
||
|
|
|
||
|
|
### Multi-Region
|
||
|
|
- Use cloud storage with appropriate region selection
|
||
|
|
- Consider CDN integration for better performance
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
**Storage backend not initialized:**
|
||
|
|
- Check configuration syntax
|
||
|
|
- Verify credentials for cloud backends
|
||
|
|
- Ensure storage directories/buckets exist
|
||
|
|
|
||
|
|
**Permission denied:**
|
||
|
|
- Check file system permissions for local storage
|
||
|
|
- Verify IAM policies for S3
|
||
|
|
- Confirm B2 application key permissions
|
||
|
|
|
||
|
|
**Large file uploads failing:**
|
||
|
|
- Check `MaxFileSize` configuration
|
||
|
|
- Verify network timeouts
|
||
|
|
- Consider multipart upload for large files
|