Refactor applications logic to simplify multiple `if` statements for databases (Redis, PostgreSQL, MongoDB)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 37.4k
- Forks
- 3k
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 73
Description
What problem will this feature address?
Currently in the codebase we have multiple places where logic is the same for different services which makes potential contributors harder to implement some features. It also makes harder to use LLM to assist because there are too many places we need to change due that spaghetti.
Describe the solution you'd like
Redis, PostgreSQL and other specific services (including templates) are just applications, but with specific requirements (inital volumes setup, configuration, specific backups, e.x. PostgreSQL, Redis). My proposal is to create a generic application with additional template syntax or DSL to allow us to reduce amount of duplicated code and simplify an architecture.
It also opens possibility to create more advanced templates by community, for example for Clickhouse which requires to have specific configuration, volume backups or for more complex applications like Langfuse which requires to deploy 5 services (frontend, backend, PostgreSQL, Redis, Clickhouse) at once to be able to operate
It probably requires fundamental refactoring (major version) because there are too many places coupled to it. So probably needs to make a painless migration to migrate everything to a generic configuration.
This is code which could be simplified to just single statement.
const value = await db
.insert(mounts)
.values({
...rest,
...(input.serviceType === "application" && {
applicationId: serviceId,
}),
...(input.serviceType === "postgres" && {
postgresId: serviceId,
}),
...(input.serviceType === "mariadb" && {
mariadbId: serviceId,
}),
...(input.serviceType === "mongo" && {
mongoId: serviceId,
}),
...(input.serviceType === "mysql" && {
mysqlId: serviceId,
}),
...(input.serviceType === "redis" && {
redisId: serviceId,
}),
...(input.serviceType === "compose" && {
composeId: serviceId,
}),
})
.returning()
.then((value) => value[0])
switch (serviceType) {
case "application":
sqlChunks.push(eq(mounts.applicationId, serviceId));
break;
case "postgres":
sqlChunks.push(eq(mounts.postgresId, serviceId));
break;
case "mariadb":
sqlChunks.push(eq(mounts.mariadbId, serviceId));
break;
case "mongo":
sqlChunks.push(eq(mounts.mongoId, serviceId));
break;
case "mysql":
sqlChunks.push(eq(mounts.mysqlId, serviceId));
break;
case "redis":
sqlChunks.push(eq(mounts.redisId, serviceId));
break;
default:
throw new Error(`Unknown service type: ${serviceType}`);
Describe alternatives you've considered
Additional context
No response
Will you send a PR to implement it?
Maybe, need help
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by mapping the duplicated serviceType branches shown in the mounts insert and filtering switch, then locate the other application-specific logic for Redis, PostgreSQL, MongoDB and templates. Define the scope of a generic application configuration and migration path, and verify that existing services, backups, volumes and templates retain their behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- clickhouse, mariadb, mongodb, mysql, postgresql, redis, typescript
- Domain
- backend, databases, devops
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100