This document outlines the data architecture for the IdeaScore application, with a particular focus on preventing data conflicts with other applications in the charBuildSuperapp ecosystem.
All tables in the IdeaScore application will follow these naming conventions:
- Prefix all tables with
ideascore_to prevent naming conflicts with other applications - Include a version suffix (e.g.,
_v1) to support schema evolution - Examples:
ideascore_ideas_v1,ideascore_tags_v1, etc.
-- Example of proper table naming
CREATE TABLE IF NOT EXISTS ideascore_ideas_v1 (
id INTEGER PRIMARY KEY AUTOINCREMENT,
-- other fields
);
All queries must include user email filtering to ensure users only see their own data:
- Every table must include a
user_emailcolumn - Every query must filter by the user's email
- Composite indexes should include
user_emailfor performance
-- Example of proper user isolation in a query
SELECT * FROM ideascore_ideas_v1
WHERE user_email = ?
ORDER BY created_at DESC;
To ensure consistent data access patterns, we will create database utility functions that:
- Always include appropriate table prefixes
- Always include user isolation
- Implement proper error handling
- Use parameterized queries to prevent SQL injection
// Example of a proper database function
async function getUserIdeas(email, sortBy = 'created_at', order = 'DESC') {
const validSortFields = ['created_at', 'title', 'effort_score', 'payoff_score', 'ratio'];
const sortField = validSortFields.includes(sortBy) ? sortBy : 'created_at';
try {
return await sqlite.execute(
`SELECT * FROM ideascore_ideas_v1
WHERE user_email = ? AND is_deleted = 0
ORDER BY ${sortField} ${order === 'ASC' ? 'ASC' : 'DESC'}`,
[email]
);
} catch (error) {
console.error('Database error in getUserIdeas:', error);
throw new Error('Failed to retrieve ideas');
}
}
Database tables should be initialized in a modular way that doesn't interfere with other applications:
async function initializeIdeaScoreDatabase() {
console.log("Initializing IdeaScore database...");
const SCHEMA_VERSION = 1;
try {
// Create ideas table
await sqlite.execute(`
CREATE TABLE IF NOT EXISTS ideascore_ideas_v1 (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
description TEXT,
effort_score INTEGER NOT NULL CHECK(effort_score BETWEEN 1 AND 10),
payoff_score INTEGER NOT NULL CHECK(payoff_score BETWEEN 1 AND 10),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
user_email TEXT NOT NULL,
is_deleted BOOLEAN DEFAULT 0
)
`);
// Create index for user isolation
await sqlite.execute(`
CREATE INDEX IF NOT EXISTS idx_ideascore_ideas_user_email
ON ideascore_ideas_v1(user_email)
`);
console.log("IdeaScore database initialized successfully");
return SCHEMA_VERSION;
} catch (error) {
console.error("IdeaScore database initialization error:", error);
throw error;
}
}
The context object passed from the main handler provides access to shared resources. We should use it consistently:
// Example handler showing proper context usage
export default async function(req, context) {
const { email, sqlite, basePath, relativePath } = context;
// Initialize our specific database tables
const SCHEMA_VERSION = await initializeIdeaScoreDatabase();
// Continue with request handling...
}
- Never modify shared tables: Only modify tables that belong to the IdeaScore application
- Use transactions for operations that modify multiple records
- Validate all input data before database operations
- Implement soft deletes using
is_deletedflags rather than actual DELETE operations - Log database errors with enough context to debug but without exposing sensitive data
- Implement periodic data backup mechanisms
- Version your queries along with your schema
Before deploying any changes, test that:
- Data from one application doesn't appear in another
- One user's data doesn't appear for another user
- Schema changes don't affect other applications
- Error handling properly captures and reports database issues
As the application grows, consider:
- Implementing a more robust ORM-like layer
- Adding database migration tools
- Considering data partitioning strategies
- Implementing more advanced access control
- Adding audit logging for sensitive operations
By following these guidelines, we can ensure that the IdeaScore application maintains proper data isolation while still benefiting from the shared infrastructure of the charBuildSuperapp ecosystem.