Skip to content
Merged
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
1 change: 0 additions & 1 deletion AGENTS.md

This file was deleted.

131 changes: 131 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

RocketAdmin is a database administration panel that allows users to manage database connections, tables, and data. It consists of multiple components in a monorepo structure:

- **backend/** - NestJS API server (TypeScript, ES modules)
- **frontend/** - Angular 19 web application (standalone components)
- **rocketadmin-agent/** - NestJS agent for connecting to databases behind firewalls
- **autoadmin-ws-server/** - WebSocket server for agent communication
- **shared-code/** - Shared data access layer and utilities used by backend and agent

## Development Commands

### Backend

```bash
cd backend
pnpm start:dev # Start dev server with hot reload
pnpm build # Build for production
pnpm lint # ESLint with auto-fix
pnpm test # Run non-saas AVA tests (serial)
pnpm test-all # Run all AVA tests (5min timeout, serial)
pnpm test-saas # Run SaaS-specific tests
```

### Frontend

```bash
cd frontend
yarn start # Start Angular dev server
yarn build # Production build
yarn test:ci # Run tests headlessly (CI mode)
yarn test --browsers=ChromeHeadlessCustom --no-watch --no-progress # Headless tests
yarn lint # TSLint (deprecated, needs ESLint migration)
```

### Running Backend Tests with Docker

The project uses `just` for test orchestration:

```bash
just test # Run all backend tests with Docker Compose
just test "path/to/test.ts" # Run specific test file
```

This spins up test databases (MySQL, PostgreSQL, MSSQL, Oracle, MongoDB, DynamoDB) via `docker-compose.tst.yml`.

### Migrations

```bash
cd backend
pnpm build # Must build first
pnpm migration:generate src/migrations/MigrationName # Generate migration
pnpm migration:run # Run pending migrations
pnpm migration:revert # Revert last migration
```

## Architecture

### Monorepo Structure

- Uses pnpm workspaces with packages: `backend`, `rocketadmin-agent`, `shared-code`
- `shared-code` is imported as `@rocketadmin/shared-code` workspace dependency
- Frontend is a separate Angular project (not a workspace member)

### Backend (NestJS)

- **Entities pattern**: Each entity has its own directory under `src/entities/` containing:
- `*.entity.ts` - TypeORM entity
- `*.module.ts` - NestJS module
- `*.controller.ts` - REST endpoints
- `*.service.ts` - Business logic (use cases)
- `dto/` - Request/response DTOs with class-validator decorators
- `*.controller.ee.ts` - Enterprise edition controllers (SaaS features)
- **Guards**: Authentication and authorization in `src/guards/`
- **Data access**: Uses `shared-code` for database operations via Knex
- **Testing**: AVA test framework with tests in `test/ava-tests/`
- `non-saas-tests/` - Core functionality tests
- `saas-tests/` - SaaS-specific feature tests
- `complex-table-tests/` - Complex table operation tests

### Frontend (Angular 19)

See `frontend/CLAUDE.md` for detailed frontend architecture.

Key points:
- Standalone components (no NgModules)
- BehaviorSubject-based state management (no NgRx)
- Multi-environment builds (development, production, saas, saas-production)
- Jasmine/Karma testing with ChromeHeadless

### Shared Code

Located in `shared-code/src/`:
- `data-access-layer/` - Database abstraction supporting MySQL, PostgreSQL, MSSQL, Oracle, MongoDB, DynamoDB, Cassandra, Elasticsearch
- `knex-manager/` - Knex connection management
- `caching/` - LRU cache utilities
- `helpers/` - Shared utilities

### Agent Architecture

The rocketadmin-agent connects to databases in private networks:
1. Agent runs inside customer's network
2. Connects to `autoadmin-ws-server` via WebSocket
3. Backend communicates with agent through WebSocket server
4. Agent executes database queries and returns results

## Database Support

The application supports: MySQL, PostgreSQL, MongoDB, DynamoDB, Cassandra, OracleDB, MSSQL, Elasticsearch, Redis

Database-specific DAOs are in `shared-code/src/data-access-layer/`.

## Testing Database Connections

Test databases are defined in `docker-compose.tst.yml`:
- MySQL: `testMySQL-e2e-testing:3306`
- PostgreSQL: `testPg-e2e-testing:5432`
- MSSQL: `mssql-e2e-testing:1433`
- Oracle: `test-oracle-e2e-testing:1521`
- MongoDB: `test-mongo-e2e-testing:27017`
- DynamoDB: `test-dynamodb-e2e-testing:8000`

## Coding Conventions

### Class Member Ordering

- Private methods must be placed at the end of the class, after all public methods
7 changes: 3 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ just test # Run all backend tests with Docker Compose
just test "path/to/test.ts" # Run specific test file
```

This spins up test databases (MySQL, PostgreSQL, MSSQL, Oracle, IBM DB2, MongoDB, DynamoDB) via `docker-compose.tst.yml`.
This spins up test databases (MySQL, PostgreSQL, MSSQL, Oracle, MongoDB, DynamoDB) via `docker-compose.tst.yml`.

### Migrations

Expand Down Expand Up @@ -95,7 +95,7 @@ Key points:
### Shared Code

Located in `shared-code/src/`:
- `data-access-layer/` - Database abstraction supporting MySQL, PostgreSQL, MSSQL, Oracle, MongoDB, DynamoDB, IBM DB2, Cassandra, Elasticsearch
- `data-access-layer/` - Database abstraction supporting MySQL, PostgreSQL, MSSQL, Oracle, MongoDB, DynamoDB, Cassandra, Elasticsearch
- `knex-manager/` - Knex connection management
- `caching/` - LRU cache utilities
- `helpers/` - Shared utilities
Expand All @@ -110,7 +110,7 @@ The rocketadmin-agent connects to databases in private networks:

## Database Support

The application supports: MySQL, PostgreSQL, MongoDB, DynamoDB, Cassandra, OracleDB, MSSQL, IBM DB2, Elasticsearch, Redis
The application supports: MySQL, PostgreSQL, MongoDB, DynamoDB, Cassandra, OracleDB, MSSQL, Elasticsearch, Redis

Database-specific DAOs are in `shared-code/src/data-access-layer/`.

Expand All @@ -121,7 +121,6 @@ Test databases are defined in `docker-compose.tst.yml`:
- PostgreSQL: `testPg-e2e-testing:5432`
- MSSQL: `mssql-e2e-testing:1433`
- Oracle: `test-oracle-e2e-testing:1521`
- IBM DB2: `test-ibm-db2-e2e-testing:50000`
- MongoDB: `test-mongo-e2e-testing:27017`
- DynamoDB: `test-dynamodb-e2e-testing:8000`

Expand Down
3 changes: 1 addition & 2 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"test-all": "node _run-with-timing.mjs ava --timeout=5m",
"test-all-parallel": "AVA_CONCURRENCY=8 node _run-with-timing.mjs ava --timeout=5m",
"test-saas": "node _run-with-timing.mjs ava test/ava-tests/saas-tests/*",
"test-fast": "AVA_CONCURRENCY=6 node _run-with-timing.mjs ava --timeout=5m 'test/ava-tests/non-saas-tests/!(*oracle*|*ibmdb2*|*cassandra*|*elasticsearch*).test.ts' 'test/ava-tests/saas-tests/!(*oracle*|*ibmdb2*|*cassandra*|*elasticsearch*).test.ts'",
"test-fast": "AVA_CONCURRENCY=6 node _run-with-timing.mjs ava --timeout=5m 'test/ava-tests/non-saas-tests/!(*oracle*|*cassandra*|*elasticsearch*).test.ts' 'test/ava-tests/saas-tests/!(*oracle*|*cassandra*|*elasticsearch*).test.ts'",
"typeorm": "ts-node -r tsconfig-paths/register ../node_modules/.bin/typeorm",
"migration:generate": "pnpm run typeorm migration:generate -d dist/src/shared/config/datasource.config.js",
"migration:create": "pnpm run typeorm migration:create -d dist/src/shared/config/datasource.config.js",
Expand Down Expand Up @@ -109,7 +109,6 @@
"@types/body-parser": "^1.19.6",
"@types/cookie-parser": "^1.4.10",
"@types/express": "^5.0.6",
"@types/ibm_db": "^3.2.0",
"@types/json2csv": "^5.0.7",
"@types/node": "^24.10.1",
"@types/supertest": "^7.2.0",
Expand Down
3 changes: 0 additions & 3 deletions backend/src/ai-core/tools/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ export function convertDbTypeToReadableString(dataType: ConnectionTypesEnum): st
case ConnectionTypesEnum.oracledb:
case ConnectionTypesEnum.agent_oracledb:
return 'Oracle DB';
case ConnectionTypesEnum.ibmdb2:
case ConnectionTypesEnum.agent_ibmdb2:
return 'IBM DB2';
case ConnectionTypesEnum.clickhouse:
case ConnectionTypesEnum.agent_clickhouse:
return 'ClickHouse';
Expand Down
3 changes: 0 additions & 3 deletions backend/src/ai-core/tools/query-validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,6 @@ export function wrapQueryWithLimit(query: string, databaseType: ConnectionTypesE
case ConnectionTypesEnum.mssql:
case ConnectionTypesEnum.agent_mssql:
return `SELECT * FROM (${queryWithoutSemicolon}) AS ai_query LIMIT ${limit}`;
case ConnectionTypesEnum.ibmdb2:
case ConnectionTypesEnum.agent_ibmdb2:
return `SELECT * FROM (${queryWithoutSemicolon}) AS ai_query FETCH FIRST ${limit} ROWS ONLY`;
case ConnectionTypesEnum.oracledb:
case ConnectionTypesEnum.agent_oracledb:
return `SELECT * FROM (${queryWithoutSemicolon}) WHERE ROWNUM <= ${limit}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ export const customAgentRepositoryExtension: IAgentRepository = {
return 'MYSQL-TEST-AGENT-TOKEN';
case ConnectionTypeTestEnum.agent_postgres:
return 'POSTGRES-TEST-AGENT-TOKEN';
case ConnectionTypeTestEnum.agent_ibmdb2:
return 'IBMDB2-TEST-AGENT-TOKEN';
case ConnectionTypeTestEnum.agent_mongodb:
return 'MONGODB-TEST-AGENT-TOKEN';
case ConnectionTypeTestEnum.agent_redis:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ const SQL_CONNECTION_TYPES: ReadonlySet<string> = new Set<string>([
ConnectionTypesEnum.mysql2,
ConnectionTypesEnum.oracledb,
ConnectionTypesEnum.mssql,
ConnectionTypesEnum.ibmdb2,
ConnectionTypesEnum.clickhouse,
ConnectionTypesEnum.agent_postgres,
ConnectionTypesEnum.agent_mysql,
ConnectionTypesEnum.agent_oracledb,
ConnectionTypesEnum.agent_mssql,
ConnectionTypesEnum.agent_ibmdb2,
ConnectionTypesEnum.agent_clickhouse,
]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,9 @@ Multi-proposal rules:
- For a single-change request, supply a "proposals" array of length 1 — same content as before.

Rules for the generated SQL:
- Target dialect is ${dialect}. Use the correct identifier quoting (double quotes for PostgreSQL/Oracle/DB2, backticks for MySQL/ClickHouse, square brackets or double quotes for Microsoft SQL Server) and the correct syntax for data types, autoincrement, and constraints.
- Target dialect is ${dialect}. Use the correct identifier quoting (double quotes for PostgreSQL/Oracle, backticks for MySQL/ClickHouse, square brackets or double quotes for Microsoft SQL Server) and the correct syntax for data types, autoincrement, and constraints.
- For Microsoft SQL Server, use IDENTITY for autoincrement, NVARCHAR/VARCHAR for strings, and name primary/foreign keys explicitly (e.g. CONSTRAINT PK_tbl PRIMARY KEY ...) so they are referenceable in rollback DROP CONSTRAINT statements.
- For Oracle DB, use NUMBER/VARCHAR2, and GENERATED BY DEFAULT AS IDENTITY for autoincrement. ALTER TABLE ... MODIFY is the column-change syntax.
- For IBM DB2, use BIGINT GENERATED BY DEFAULT AS IDENTITY and VARCHAR. ALTER TABLE ... ALTER COLUMN ... SET DATA TYPE is the column-change syntax.
- For ClickHouse: every CREATE TABLE MUST include a table engine (prefer \`ENGINE = MergeTree()\`) followed by an \`ORDER BY (<column or tuple>)\` clause — ClickHouse has no conventional PRIMARY KEY; the sort/primary key is the \`ORDER BY\` tuple. Use types like \`UInt32\`, \`UInt64\`, \`Int64\`, \`String\`, \`Float64\`, \`DateTime\`, \`Date\`, \`UUID\`, \`Nullable(T)\` (wrap a type to allow NULL). There is no autoincrement — use a plain numeric type the user populates. Column additions use \`ALTER TABLE t ADD COLUMN c T\`, drops use \`ALTER TABLE t DROP COLUMN c\`, type changes use \`ALTER TABLE t MODIFY COLUMN c T\`. Do NOT emit \`ON CLUSTER\` clauses; the target is a single-node server. There are NO true transactions, so rollback is a best-effort compensating DDL (e.g. add-column forward / drop-column rollback). Do NOT propose foreign keys (ClickHouse does not enforce them). Indexes in ClickHouse are DATA SKIPPING indexes created with \`ALTER TABLE t ADD INDEX idx_name col TYPE minmax GRANULARITY 4\`; rollback is \`ALTER TABLE t DROP INDEX idx_name\`. Avoid \`DROP TABLE IF EXISTS\` unless the user asked.
- For Cassandra (CQL): every CREATE TABLE MUST declare a \`PRIMARY KEY\` inline, either as a column-level \`PRIMARY KEY\` on one column or as a trailing \`PRIMARY KEY ((partition_key_cols), clustering_key_cols)\` clause. Use CQL types: \`UUID\`, \`TIMEUUID\`, \`TEXT\`, \`VARCHAR\`, \`ASCII\`, \`INT\`, \`BIGINT\`, \`SMALLINT\`, \`TINYINT\`, \`FLOAT\`, \`DOUBLE\`, \`DECIMAL\`, \`BOOLEAN\`, \`TIMESTAMP\`, \`DATE\`, \`TIME\`, \`BLOB\`, \`INET\`, \`LIST<T>\`, \`SET<T>\`, \`MAP<K,V>\`. There is NO autoincrement — prefer \`UUID\` partition keys. Do NOT propose foreign keys (Cassandra does not enforce them). Do NOT propose \`ALTER COLUMN\` type-change DDL — CQL only supports renaming primary-key columns and adding/dropping non-primary-key columns. Column additions use \`ALTER TABLE t ADD c T\` (no \`COLUMN\` keyword), drops use \`ALTER TABLE t DROP c\`. Indexes are \`CREATE INDEX idx_name ON t (col)\` with rollback \`DROP INDEX idx_name\`. There are NO transactions; rollback is a best-effort compensating DDL. Do NOT emit \`CREATE KEYSPACE\`, \`DROP KEYSPACE\`, \`USE\`, or materialized-view DDL.
- Both forwardSql and rollbackSql MUST be single DDL statements. No semicolons terminating a chain. No multi-statement scripts.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ const SUPPORTED_DIALECTS: ReadonlySet<ConnectionTypesEnum> = new Set([
ConnectionTypesEnum.mysql2,
ConnectionTypesEnum.mssql,
ConnectionTypesEnum.oracledb,
ConnectionTypesEnum.ibmdb2,
ConnectionTypesEnum.mongodb,
ConnectionTypesEnum.clickhouse,
ConnectionTypesEnum.agent_clickhouse,
Expand All @@ -24,7 +23,7 @@ export function isDialectSupported(connectionType: ConnectionTypesEnum): boolean
export function assertDialectSupported(connectionType: ConnectionTypesEnum): void {
if (!isDialectSupported(connectionType)) {
throw new BadRequestException(
`Schema changes via AI are not yet supported for "${connectionType}". Supported: PostgreSQL, MySQL, Microsoft SQL Server, Oracle DB, IBM DB2, MongoDB, ClickHouse, DynamoDB, Cassandra, Elasticsearch.`,
`Schema changes via AI are not yet supported for "${connectionType}". Supported: PostgreSQL, MySQL, Microsoft SQL Server, Oracle DB, MongoDB, ClickHouse, DynamoDB, Cassandra, Elasticsearch.`,
);
}
}
Expand Down Expand Up @@ -57,8 +56,6 @@ const SQL_PARSER_DIALECTS: Record<string, string> = {
[ConnectionTypesEnum.agent_mysql]: 'MySQL',
[ConnectionTypesEnum.mssql]: 'TransactSQL',
[ConnectionTypesEnum.agent_mssql]: 'TransactSQL',
[ConnectionTypesEnum.ibmdb2]: 'DB2',
[ConnectionTypesEnum.agent_ibmdb2]: 'DB2',
};

export function connectionTypeToParserDialect(connectionType: ConnectionTypesEnum): string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ export class ExportCSVFromTableUseCase
//todo: transfer data as a stream from clint to server
if (
connection.type === 'oracledb' ||
connection.type === 'ibmdb2' ||
connection.type === 'mongodb' ||
connection.type === 'dynamodb' ||
connection.type === 'elasticsearch' ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,6 @@ const SQL_CONNECTION_TYPES: ConnectionTypesEnum[] = [
ConnectionTypesEnum.agent_mssql,
ConnectionTypesEnum.oracledb,
ConnectionTypesEnum.agent_oracledb,
ConnectionTypesEnum.ibmdb2,
ConnectionTypesEnum.agent_ibmdb2,
ConnectionTypesEnum.clickhouse,
ConnectionTypesEnum.agent_clickhouse,
ConnectionTypesEnum.cassandra,
Expand Down
5 changes: 2 additions & 3 deletions backend/src/helpers/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export type TestConnectionsFromJSON = {
'test-mssql': string;
'test-oracle': string;
'test-mongo': string;
'test-ibmdb2': string;
};

export const Constants = {
Expand Down Expand Up @@ -57,11 +56,11 @@ export const Constants = {
MORNING_CRON_KEY: 2,
CONNECTION_KEYS_NONE_PERMISSION: ['id', 'title', 'database', 'type', 'connection_properties', 'isTestConnection'],
FREE_PLAN_USERS_COUNT: 3,
NON_FREE_PLAN_CONNECTION_TYPES: [ConnectionTypesEnum.ibmdb2, ConnectionTypesEnum.mssql, ConnectionTypesEnum.oracledb],
NON_FREE_PLAN_CONNECTION_TYPES: [ConnectionTypesEnum.mssql, ConnectionTypesEnum.oracledb],
MAX_FILE_SIZE_IN_BYTES: 10485760,
MAX_COMPANY_LOGO_SIZE: 5242880,
MAX_COMPANY_FAVICON_SIZE: 5242880,
PAID_CONNECTIONS_TYPES: [ConnectionTypesEnum.oracledb, ConnectionTypesEnum.ibmdb2, ConnectionTypesEnum.mssql],
PAID_CONNECTIONS_TYPES: [ConnectionTypesEnum.oracledb, ConnectionTypesEnum.mssql],

VERIFICATION_STRING_WHITELIST: () => {
const numbers = [...Array(10).keys()].map((num) => num.toString());
Expand Down
2 changes: 0 additions & 2 deletions backend/src/helpers/is-connection-entity-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export function isConnectionEntityAgent(connection: ConnectionEntity | CreateCon
ConnectionTypesEnum.agent_mysql,
ConnectionTypesEnum.agent_oracledb,
ConnectionTypesEnum.agent_mssql,
ConnectionTypesEnum.agent_ibmdb2,
ConnectionTypesEnum.agent_mongodb,
ConnectionTypesEnum.agent_cassandra,
ConnectionTypesEnum.agent_redis,
Expand All @@ -27,7 +26,6 @@ export function isConnectionTypeAgent(type: ConnectionTypesEnum | string | null
ConnectionTypeTestEnum.agent_mysql,
ConnectionTypeTestEnum.agent_oracledb,
ConnectionTypeTestEnum.agent_mssql,
ConnectionTypeTestEnum.agent_ibmdb2,
ConnectionTypeTestEnum.agent_mongodb,
ConnectionTypeTestEnum.agent_cassandra,
ConnectionTypesEnum.agent_redis,
Expand Down
16 changes: 0 additions & 16 deletions backend/src/shared/config/app-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,6 @@ export interface TestDbConfig {
database: string | null;
authSource: string | null;
};
ibmdb2: {
host: string | null;
port: number | null;
username: string | null;
password: string | null;
database: string | null;
schema: string | null;
};
}

const AUTOADMIN_SUPPORT_MAIL = 'support@autoadmin.org';
Expand Down Expand Up @@ -220,14 +212,6 @@ export class AppConfig {
database: readString('MONGO_CONNECTION_DATABASE'),
authSource: readString('MONGO_CONNECTION_AUTH_SOURCE'),
}),
ibmdb2: Object.freeze({
host: readString('IBM_DB2_CONNECTION_HOST'),
port: readInt('IBM_DB2_CONNECTION_PORT'),
username: readString('IBM_DB2_CONNECTION_USERNAME'),
password: readString('IBM_DB2_CONNECTION_PASSWORD'),
database: readString('IBM_DB2_CONNECTION_DATABASE'),
schema: readString('IBM_DB2_CONNECTION_SCHEMA'),
}),
});

Object.freeze(this);
Expand Down
Loading
Loading