From d20245f19f955de6c39d3bf0afa386c1af726a89 Mon Sep 17 00:00:00 2001 From: Avisek Date: Fri, 8 May 2026 18:06:47 +0530 Subject: [PATCH 1/5] refactor: update readme and replace Taskfile with Makefile targets --- README.md | 192 ++++++++++++++++----------------------------------- Taskfile.yml | 91 ------------------------ makefile | 62 ++++++++++++----- 3 files changed, 104 insertions(+), 241 deletions(-) delete mode 100644 Taskfile.yml diff --git a/README.md b/README.md index 642b3b1..db22119 100644 --- a/README.md +++ b/README.md @@ -1,155 +1,81 @@

RowSQL

-

+ +

License: MIT - Go Version - Made with React

-> A lightweight, cross-platform database management tool for PostgreSQL, MySQL, and SQLite with a modern web-based interface. - -RowSQL provides an intuitive web UI to manage your databases without the complexity of heavy desktop applications. Perfect for developers who need quick access to their data with powerful filtering, editing, and query tracking capabilities. +RowSQL is a simple tool to view and manage your databases. It provides a clean web interface to look at your information, edit records, and track your activity without needing complex desktop software. ![Demo](./resources/demo.gif) ## Features -- [x] Represent your sql data in a user-friendly UI. -- [x] Perform various SQL operations – Easily insert, update, or delete records using intuitive web forms. -- [x] Track query history – Maintain a "Recent Activity" log to see every change made to your database using RowSQL. -- [x] Inspect Table Structures -- [x] Shows rows the way you want them - you choose the order, filter - -## Installation - -```bash -curl -fsSL https://raw.githubusercontent.com/biisal/rowsql/refs/heads/main/install | bash -``` - -## How to Use? - -1. Create a .env file in your home directory's rowsql folder: - - Unix: ~/.rowsql/.env - - Windows: %USERPROFILE%\\.rowsql\\.env - -2. .env file should contain the following - -``` -DBSTRING=my.db -PORT=8000 -LOG_FILE_PATH="~/.rowsql/rowsql.log" -``` - -3. run `rowsql` -4. open http://127.0.0.1:8000 in your browser - -### .env Variables Explanation - -**DBSTRING** is the connection string to your database. - -- For **SQLite**, this is the path to your `.db` file. -- For **PostgreSQL**/**MySQL**, this is the PostgreSQL/MySQL connection string. - - `DBSTRING=postgres://admin:admin@127.0.0.1:5432/admin_db` -- RowSQL automatically detects the database type from the connection string. - -**PORT** - -- The port number that RowSQL listens on. Using that port number, you can access RowSQL's web interface. - -**LOG_FILE_PATH** - -- The file path where RowSQL writes its Error logs. - -## Development - -### Prerequisites +- **Easy Viewing**: See your data in a clear, organized table. +- **Direct Editing**: Add, update, or delete records using simple forms. +- **Activity Log**: See a history of the changes you've made. +- **Filtering**: Find exactly what you need with easy search and sort options. +- **Multiple Databases**: Works with SQLite, MySQL, and PostgreSQL. -- **Go** 1.25.3 or higher -- **Node.js** and **pnpm** (for building the frontend) -- **Air** (optional, for hot-reloading during development) +## Quick Install -### Building from Source - -1. Clone the repository: - ```bash - git clone https://github.com/biisal/rowsql.git - cd rowsql - ``` - -2. Install frontend dependencies: - ```bash - cd frontend && pnpm install && cd .. - ``` - -3. Build the project: - ```bash - make build - ``` - This will build the frontend and compile the Go binary to `bin/rowsql`. - -4. Run the binary: - ```bash - ./bin/rowsql - ``` - -### Development Mode - -For development with hot-reloading: +Run this command in your terminal to install RowSQL: ```bash -make dev -``` - -This runs both the frontend dev server and backend with Air for automatic reloading. - -Alternatively, run them separately: -- Frontend only: `make frontend-dev` -- Backend only: `make backend-dev` - -### Project Structure - -``` -rowsql/ -├── cmd/server/ # Application entry point -├── internal/ # Internal packages -│ ├── database/ # Database connection & type handling -│ ├── router/ # HTTP routes & handlers -│ ├── service/ # Business logic -│ └── logger/ # Logging utilities -├── frontend/ # React + Vite frontend -├── configs/ # Configuration management -└── resources/ # Static resources +curl -fsSL https://raw.githubusercontent.com/biisal/rowsql/refs/heads/main/install | bash ``` -## Performance Considerations - -### Database Size Recommendations - -- **SQLite**: Works well with databases up to several GB. Performance may degrade with very large tables (100M+ rows). -- **PostgreSQL/MySQL**: Suitable for databases of any size, but consider the following: - - Large result sets (>10,000 rows) are paginated automatically - - Complex queries on large tables may take time; use filters to narrow results - -### Best Practices - -1. **Index your tables**: Ensure frequently queried columns have appropriate indexes for faster data retrieval. - -2. **Limit result sets**: When working with large tables, use the built-in filtering and sorting features to limit the data loaded. - -3. **Connection pooling**: RowSQL uses efficient connection pooling, but avoid running multiple instances against the same database unnecessarily. - -4. **Memory usage**: RowSQL loads data on-demand. For very large result sets, pagination prevents excessive memory consumption. - -5. **Network latency**: For remote databases (PostgreSQL/MySQL), ensure good network connectivity for optimal performance. +## How to use + +Follow these steps to get started: + +1. **Start RowSQL**: Type `rowsql` in your terminal. +2. **Setup Configuration**: If it's your first run, RowSQL will ask to create a default configuration file. Type `y` and press Enter. +3. **Find your config**: The settings are stored in a file named `config.json` in your home directory: + - **Unix/Mac**: `~/.rowsql/config.json` + - **Windows**: `%USERPROFILE%\.rowsql\config.json` +4. **Connect your database**: Open `config.json` and add your database details. Here is a full example with multiple databases: + ```json + { + "connections": [ + { + "port": 8000, + "db_string": "my_local_data.db" + }, + { + "port": 8081, + "db_string": "postgres://admin:password@localhost:5432/customers" + } + ], + "disable_auto_update": false, + "max_items_per_page": 50, + "log_file_path": "/home/user/.rowsql/rowsql.log" + } + ``` +5. **Open in browser**: Visit `http://localhost:8000` to start managing your data. + +### Configuration Details + +Here is what each setting in your `config.json` does: + +- **`connections`**: A list of your database settings. You can add more than one database here. + - **`port`**: The number you type into your browser to see your data (for example, `8000`). + - **`db_string`**: The location of your database (either a file path or a web address). +- **`disable_auto_update`**: If set to `true`, RowSQL will stop checking for new versions automatically. +- **`max_items_per_page`**: The maximum number of rows to show on one page (default is 100). +- **`log_file_path`**: The file where RowSQL saves error messages if something goes wrong. + +### Connection Examples + +RowSQL uses a "connection string" (`db_string`) to find your database. Here are common formats: + +- **SQLite**: Use the path to your database file (for example, `my_data.db`). +- **PostgreSQL or MySQL**: Use a standard connection address (for example, `postgres://user:password@localhost:5432/my_db`). ## Contributing -Contributions are welcome! Here's how you can help: - -1. **Report bugs**: Open an issue describing the bug and steps to reproduce it. -2. **Suggest features**: Share your ideas for new features or improvements. -3. **Submit pull requests**: Fork the repo, make your changes, and submit a PR. +We welcome your help! If you find a bug or have a suggestion, please open an issue or submit a pull request. -Please ensure your code follows the existing style and includes appropriate tests where applicable. +For technical details and how to build from source, see [DEVELOPMENT.md](./DEVELOPMENT.md). ## License diff --git a/Taskfile.yml b/Taskfile.yml deleted file mode 100644 index 514c4ef..0000000 --- a/Taskfile.yml +++ /dev/null @@ -1,91 +0,0 @@ -# yaml-language-server: $schema=https://taskfile.dev/schema.json - -version: "3" - -vars: - GREETING: Hello from RowSQL! - -tasks: - default: - desc: Print a greeting message - cmds: - - echo "{{.GREETING}}" - silent: true - - backend-build: - desc: build backend application - cmds: - - go run ./cmd/schema/main.go - - go build -o bin/rowsql ./cmd/server - frontend-build: - desc: build frontend application - cmds: - - cd ./frontend && pnpm run build - - backend-dev: - desc: run backend server in development mode - cmds: - - air -c air.toml - - frontend-dev: - desc: run frontend server in development mode - cmds: - - cd ./frontend/ && pnpm run dev - - dev: - desc: Run the application in development mode - deps: [backend-dev, frontend-dev] - - build: - desc: build frontend and backend - cmds: - - task: doc - - task: frontend-build - - task: backend-build - - echo "build was successful" - - run: - desc: Run the application - deps: [build] - cmds: - - ./bin/rowsql - doc: - desc: generate documentation - cmds: - - go run ./cmd/schema/... - test: - desc: test the application - cmds: - - go test ./... -failfast - - release: - desc: make a release for test - cmds: - - goreleaser release --clean --snapshot - - lint: - desc: Run linter only - cmds: - - golangci-lint run - - cd ./frontend && pnpm lint - - clean: - desc: Clean build artifacts and dependencies - cmds: - - rm -rf dist/ - - rm -rf bin/ - - rm -rf tmp/ - - rm -rf frontend/dist/ - - rm -rf frontend/node_modules/ - - install: - desc: Install dependencies - cmds: - - go mod download - - cd ./frontend && pnpm install - - format: - desc: Run gofmt - cmds: - - gofmt -w . - - cd ./frontend && pnpm run format diff --git a/makefile b/makefile index 818ba73..8552efa 100644 --- a/makefile +++ b/makefile @@ -1,27 +1,55 @@ -ensure-psql: - @systemctl is-active --quiet postgresql || sudo systemctl start postgresql +GREETING := Hello from RowSQL! -run: - ./bin/rowsql +.PHONY: default backend-build frontend-build backend-dev frontend-dev dev build run doc test release lint clean install format -frontend-dev: - cd ./frontend/ && pnpm run dev +default: + @echo "$(GREETING)" + +backend-build: + go run ./cmd/schema/main.go + go build -o bin/rowsql ./cmd/server + +frontend-build: + cd ./frontend && pnpm run build backend-dev: air -c air.toml -dev: - make -j2 frontend-dev backend-dev +frontend-dev: + cd ./frontend/ && pnpm run dev -build: - cd ./frontend && pnpm run build - go build -o bin/rowsql ./cmd/server - -build-linux: - cd ./frontend && pnpm run build - GOOS=linux GOARCH=amd64 go build -o bin/rowsql-linux ./cmd/server +dev: backend-dev frontend-dev + +build: doc frontend-build backend-build + echo "build was successful" + +run: build + ./bin/rowsql + +doc: + go run ./cmd/schema/... test: - go test ./... + go test ./... -failfast + +release: + goreleaser release --clean --snapshot + +lint: + golangci-lint run + cd ./frontend && pnpm lint + +clean: + rm -rf dist/ + rm -rf bin/ + rm -rf tmp/ + rm -rf frontend/dist/ + rm -rf frontend/node_modules/ + +install: + go mod download + cd ./frontend && pnpm install -.PHONY: frontend-dev backend-dev dev run ensure-psql +format: + gofmt -w . + cd ./frontend && pnpm run format \ No newline at end of file From e9f291bab51b24f27e115fa0ce2fe7d3222c71e2 Mon Sep 17 00:00:00 2001 From: Avisek Date: Fri, 8 May 2026 18:16:45 +0530 Subject: [PATCH 2/5] docs: add configuration warning to README and initialize DEVELOPMENT documentation alongside updated openapi schema --- DEVELOPMENT.md | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 ++ 2 files changed, 92 insertions(+) create mode 100644 DEVELOPMENT.md diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..547ac4e --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,90 @@ +# Development and Technical Details + +This document contains technical information for developers who want to contribute to RowSQL or build it from source. + +## Prerequisites + +- **Go** 1.25.3 or higher +- **Node.js** and **pnpm** (for building the frontend) +- **Air** (optional, for hot-reloading during development) + +## Building from Source + +1. Clone the repository: + ```bash + git clone https://github.com/biisal/rowsql.git + cd rowsql + ``` + +2. Install dependencies: + ```bash + make install + ``` + +3. Build the project: + ```bash + make build + ``` + This will build the frontend and compile the Go binary to `bin/rowsql`. + +4. Run the binary: + ```bash + ./bin/rowsql + ``` + +## Development Mode + +For development with hot-reloading: + +```bash +make dev +``` + +This runs both the frontend dev server and backend with Air for automatic reloading. + +Alternatively, run them separately: +- Frontend only: `make frontend-dev` +- Backend only: `make backend-dev` + +> **Note:** When using development tools like `make dev` or `air`, ensure your `config.json` contains only **one** connection. If you have multiple connections, RowSQL will prompt you to select one, which does not work correctly with `air`. + +## Configuration + +The configuration file is located in the `.rowsql` folder in your home directory: +- **Unix/Mac**: `~/.rowsql/config.json` +- **Windows**: `%USERPROFILE%\.rowsql\config.json` + +### Full Example + +```json +{ + "connections": [ + { + "port": 8000, + "db_string": "my_local_data.db", + "env": "development" + } + ], + "disable_auto_update": true, + "max_items_per_page": 100, + "min_items_per_page": 10, + "log_file_path": "/path/to/rowsql.log" +} +``` + +## Performance Considerations + +### Database Size Recommendations + +- **SQLite**: Works well with databases up to several GB. Performance may degrade with very large tables (100M+ rows). +- **PostgreSQL/MySQL**: Suitable for databases of any size, but consider the following: + - Large result sets (>10,000 rows) are paginated automatically. + - Complex queries on large tables may take time; use filters to narrow results. + +### Best Practices + +1. **Index your tables**: Ensure frequently queried columns have appropriate indexes for faster data retrieval. +2. **Limit result sets**: When working with large tables, use the built-in filtering and sorting features to limit the data loaded. +3. **Connection pooling**: RowSQL uses efficient connection pooling, but avoid running multiple instances against the same database unnecessarily. +4. **Memory usage**: RowSQL loads data on-demand. For very large result sets, pagination prevents excessive memory consumption. +5. **Network latency**: For remote databases (PostgreSQL/MySQL), ensure good network connectivity for optimal performance. diff --git a/README.md b/README.md index db22119..2a2e3ec 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,8 @@ Follow these steps to get started: "log_file_path": "/home/user/.rowsql/rowsql.log" } ``` + > **Note:** If you make changes to your configuration file, you must restart RowSQL for the new settings to take effect. + 5. **Open in browser**: Visit `http://localhost:8000` to start managing your data. ### Configuration Details From d5d0d3e8857314505adab877522decd098313790 Mon Sep 17 00:00:00 2001 From: Avisek Date: Sat, 9 May 2026 08:29:34 +0530 Subject: [PATCH 3/5] chore: remove openapi schema and initialize pnpm workspace configuration --- frontend/openapi.json | 938 ----------------------------------- frontend/pnpm-workspace.yaml | 3 + 2 files changed, 3 insertions(+), 938 deletions(-) delete mode 100644 frontend/openapi.json create mode 100644 frontend/pnpm-workspace.yaml diff --git a/frontend/openapi.json b/frontend/openapi.json deleted file mode 100644 index 1711597..0000000 --- a/frontend/openapi.json +++ /dev/null @@ -1,938 +0,0 @@ -{ - "components": { - "schemas": { - "ColType": { - "additionalProperties": true, - "properties": { - "dataType": { - "type": "string" - }, - "hasAutoIncrement": { - "type": "boolean" - }, - "hasDefault": { - "type": "boolean" - }, - "hasDigit": { - "type": "boolean" - }, - "hasSize": { - "type": "boolean" - }, - "hasValues": { - "type": "boolean" - }, - "inputType": { - "enum": [ - "text", - "number", - "checkbox", - "textarea", - "json", - "select" - ], - "type": "string" - }, - "isNull": { - "type": "boolean" - }, - "isPk": { - "type": "boolean" - }, - "isUnique": { - "type": "boolean" - } - }, - "required": [ - "dataType", - "hasSize", - "hasAutoIncrement", - "hasDefault", - "isUnique", - "isPk", - "isNull", - "inputType" - ], - "type": "object" - }, - "ColValue": { - "additionalProperties": true, - "properties": { - "columnName": { - "type": "string" - }, - "columnType": { - "$ref": "#/components/schemas/ColType" - }, - "defaultValue": {}, - "size": { - "format": "int64", - "type": "integer" - }, - "value": {} - }, - "required": ["columnName", "columnType"], - "type": "object" - }, - "CreeteNewTableInputBody": { - "additionalProperties": true, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "examples": [ - "https://example.com/schemas/CreeteNewTableInputBody.json" - ], - "format": "uri", - "readOnly": true, - "type": "string" - }, - "inputs": { - "items": { - "$ref": "#/components/schemas/ColValue" - }, - "type": ["array", "null"] - }, - "tableName": { - "type": "string" - } - }, - "required": ["tableName", "inputs"], - "type": "object" - }, - "DeleteTableRequest": { - "additionalProperties": true, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "examples": ["https://example.com/schemas/DeleteTableRequest.json"], - "format": "uri", - "readOnly": true, - "type": "string" - }, - "tableName": { - "type": "string" - }, - "verificationQuery": { - "type": "string" - } - }, - "required": ["tableName", "verificationQuery"], - "type": "object" - }, - "ErrorDetail": { - "additionalProperties": true, - "properties": { - "location": { - "description": "Where the error occurred, e.g. 'body.items[3].tags' or 'path.thing-id'", - "type": "string" - }, - "message": { - "description": "Error message text", - "type": "string" - }, - "value": { - "description": "The value at the given location" - } - }, - "type": "object" - }, - "ErrorModel": { - "additionalProperties": true, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "examples": ["https://example.com/schemas/ErrorModel.json"], - "format": "uri", - "readOnly": true, - "type": "string" - }, - "detail": { - "description": "A human-readable explanation specific to this occurrence of the problem.", - "examples": ["Property foo is required but is missing."], - "type": "string" - }, - "errors": { - "description": "Optional list of individual error details", - "items": { - "$ref": "#/components/schemas/ErrorDetail" - }, - "type": ["array", "null"] - }, - "instance": { - "description": "A URI reference that identifies the specific occurrence of the problem.", - "examples": ["https://example.com/error-log/abc123"], - "format": "uri", - "type": "string" - }, - "status": { - "description": "HTTP status code", - "examples": [400], - "format": "int64", - "type": "integer" - }, - "title": { - "description": "A short, human-readable summary of the problem type. This value should not change between occurrences of the error.", - "examples": ["Bad Request"], - "type": "string" - }, - "type": { - "default": "about:blank", - "description": "A URI reference to human-readable documentation for the error.", - "examples": ["https://example.com/errors/example"], - "format": "uri", - "type": "string" - } - }, - "type": "object" - }, - "FormDatatype": { - "additionalProperties": true, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "examples": ["https://example.com/schemas/FormDatatype.json"], - "format": "uri", - "readOnly": true, - "type": "string" - }, - "numericType": { - "items": { - "$ref": "#/components/schemas/VarianDataType" - }, - "type": ["array", "null"] - }, - "stringType": { - "items": { - "$ref": "#/components/schemas/VarianDataType" - }, - "type": ["array", "null"] - } - }, - "required": ["numericType", "stringType"], - "type": "object" - }, - "History": { - "additionalProperties": true, - "properties": { - "id": { - "format": "int64", - "type": "integer" - }, - "message": { - "type": "string" - }, - "time": { - "format": "date-time", - "type": "string" - } - }, - "required": ["id", "message", "time"], - "type": "object" - }, - "ListRowsResponse": { - "additionalProperties": true, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "examples": ["https://example.com/schemas/ListRowsResponse.json"], - "format": "uri", - "readOnly": true, - "type": "string" - }, - "activeTable": { - "type": "string" - }, - "cols": { - "items": { - "$ref": "#/components/schemas/ColValue" - }, - "type": ["array", "null"] - }, - "hasNextPage": { - "type": "boolean" - }, - "page": { - "format": "int64", - "type": "integer" - }, - "rowCount": { - "format": "int64", - "type": "integer" - }, - "rows": { - "items": { - "$ref": "#/components/schemas/RowSet" - }, - "type": ["array", "null"] - }, - "totalPages": { - "format": "int64", - "type": "integer" - } - }, - "required": [ - "page", - "rows", - "cols", - "rowCount", - "activeTable", - "hasNextPage", - "totalPages" - ], - "type": "object" - }, - "ListTablesRow": { - "additionalProperties": true, - "properties": { - "tableName": { - "type": "string" - }, - "tableSchema": { - "type": "string" - } - }, - "required": ["tableSchema", "tableName"], - "type": "object" - }, - "RowInsertOrUpdateFormOutputBody": { - "additionalProperties": true, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "examples": [ - "https://example.com/schemas/RowInsertOrUpdateFormOutputBody.json" - ], - "format": "uri", - "readOnly": true, - "type": "string" - }, - "cols": { - "items": { - "$ref": "#/components/schemas/ColValue" - }, - "type": ["array", "null"] - } - }, - "required": ["cols"], - "type": "object" - }, - "RowSet": { - "additionalProperties": true, - "properties": { - "columns": { - "items": { - "$ref": "#/components/schemas/ColValue" - }, - "type": ["array", "null"] - }, - "hash": { - "type": "string" - } - }, - "required": ["columns", "hash"], - "type": "object" - }, - "RunSQLQueryInputBody": { - "additionalProperties": true, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "examples": [ - "https://example.com/schemas/RunSQLQueryInputBody.json" - ], - "format": "uri", - "readOnly": true, - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": ["query"], - "type": "object" - }, - "RunSQLQueryOutputBody": { - "additionalProperties": true, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "examples": [ - "https://example.com/schemas/RunSQLQueryOutputBody.json" - ], - "format": "uri", - "readOnly": true, - "type": "string" - }, - "columns": { - "items": { - "type": "string" - }, - "type": ["array", "null"] - }, - "rows": { - "items": { - "items": {}, - "type": ["array", "null"] - }, - "type": ["array", "null"] - } - }, - "required": ["columns", "rows"], - "type": "object" - }, - "VarianDataType": { - "additionalProperties": true, - "properties": { - "hasAutoIncrement": { - "type": "boolean" - }, - "hasDigit": { - "type": "boolean" - }, - "hasSize": { - "type": "boolean" - }, - "hasValues": { - "type": "boolean" - }, - "isNumeric": { - "type": "boolean" - }, - "type": { - "type": "string" - } - }, - "required": [ - "type", - "hasSize", - "hasDigit", - "hasAutoIncrement", - "hasValues", - "isNumeric" - ], - "type": "object" - } - } - }, - "info": { - "title": "RowSQL API", - "version": "1.0.0" - }, - "openapi": "3.1.0", - "paths": { - "/api/v1/history": { - "get": { - "operationId": "listHistory", - "parameters": [ - { - "explode": false, - "in": "query", - "name": "page", - "schema": { - "default": 1, - "format": "int64", - "type": "integer" - } - } - ], - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/History" - }, - "type": ["array", "null"] - } - } - }, - "description": "OK" - }, - "default": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ErrorModel" - } - } - }, - "description": "Error" - } - }, - "summary": "List query history", - "tags": ["history"] - } - }, - "/api/v1/history/recent": { - "get": { - "operationId": "listRecentHistory", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/History" - }, - "type": ["array", "null"] - } - } - }, - "description": "OK" - }, - "default": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ErrorModel" - } - } - }, - "description": "Error" - } - }, - "summary": "List recent history", - "tags": ["history"] - } - }, - "/api/v1/run-sql": { - "post": { - "operationId": "runSQLQuery", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunSQLQueryInputBody" - } - } - }, - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunSQLQueryOutputBody" - } - } - }, - "description": "OK" - }, - "default": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ErrorModel" - } - } - }, - "description": "Error" - } - }, - "summary": "Run SQL query", - "tags": ["sql"] - } - }, - "/api/v1/tables": { - "delete": { - "operationId": "deleteTable", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeleteTableRequest" - } - } - }, - "required": true - }, - "responses": { - "204": { - "description": "No Content" - }, - "default": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ErrorModel" - } - } - }, - "description": "Error" - } - }, - "summary": "Delete a table", - "tags": ["tables"] - }, - "get": { - "operationId": "listTables", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/ListTablesRow" - }, - "type": ["array", "null"] - } - } - }, - "description": "OK" - }, - "default": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ErrorModel" - } - } - }, - "description": "Error" - } - }, - "summary": "List of all tables", - "tags": ["tables"] - } - }, - "/api/v1/tables/form/new": { - "get": { - "operationId": "newTableFormFileds", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/FormDatatype" - } - } - }, - "description": "OK" - }, - "default": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ErrorModel" - } - } - }, - "description": "Error" - } - }, - "summary": "Get data types for new table form", - "tags": ["tables"] - }, - "post": { - "operationId": "createNewTable", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreeteNewTableInputBody" - } - } - }, - "required": true - }, - "responses": { - "204": { - "description": "No Content" - }, - "default": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ErrorModel" - } - } - }, - "description": "Error" - } - }, - "summary": "Create a new table", - "tags": ["tables"] - } - }, - "/api/v1/tables/{tableName}": { - "get": { - "operationId": "listRows", - "parameters": [ - { - "in": "path", - "name": "tableName", - "required": true, - "schema": { - "type": "string" - } - }, - { - "explode": false, - "in": "query", - "name": "page", - "schema": { - "default": 1, - "format": "int64", - "minimum": 1, - "type": "integer" - } - }, - { - "explode": false, - "in": "query", - "name": "column", - "schema": { - "type": "string" - } - }, - { - "explode": false, - "in": "query", - "name": "order", - "schema": { - "enum": ["ASC", "DESC"], - "type": "string" - } - } - ], - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListRowsResponse" - } - } - }, - "description": "OK" - }, - "default": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ErrorModel" - } - } - }, - "description": "Error" - } - }, - "summary": "List rows of a table", - "tags": ["rows"] - } - }, - "/api/v1/tables/{tableName}/columns": { - "get": { - "operationId": "listColumns", - "parameters": [ - { - "in": "path", - "name": "tableName", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/ColValue" - }, - "type": ["array", "null"] - } - } - }, - "description": "OK" - }, - "default": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ErrorModel" - } - } - }, - "description": "Error" - } - }, - "summary": "List columns of a table", - "tags": ["columns"] - } - }, - "/api/v1/tables/{tableName}/form": { - "get": { - "operationId": "rowInsertOrUpdateForm", - "parameters": [ - { - "in": "path", - "name": "tableName", - "required": true, - "schema": { - "type": "string" - } - }, - { - "explode": false, - "in": "query", - "name": "page", - "schema": { - "default": 1, - "format": "int64", - "minimum": 1, - "type": "integer" - } - }, - { - "explode": false, - "in": "query", - "name": "hash", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RowInsertOrUpdateFormOutputBody" - } - } - }, - "description": "OK" - }, - "default": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ErrorModel" - } - } - }, - "description": "Error" - } - }, - "summary": "Get row insert/update form metadata", - "tags": ["rows"] - }, - "post": { - "operationId": "insertOrUpdateRow", - "parameters": [ - { - "in": "path", - "name": "tableName", - "required": true, - "schema": { - "type": "string" - } - }, - { - "explode": false, - "in": "query", - "name": "hash", - "schema": { - "type": "string" - } - }, - { - "explode": false, - "in": "query", - "name": "page", - "schema": { - "default": 1, - "format": "int64", - "type": "integer" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/ColValue" - }, - "type": ["array", "null"] - } - } - }, - "required": true - }, - "responses": { - "204": { - "description": "No Content" - }, - "default": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ErrorModel" - } - } - }, - "description": "Error" - } - }, - "summary": "Insert or update a row", - "tags": ["rows"] - } - }, - "/api/v1/tables/{tableName}/row/{hash}": { - "delete": { - "operationId": "deleteRow", - "parameters": [ - { - "in": "path", - "name": "tableName", - "required": true, - "schema": { - "type": "string" - } - }, - { - "in": "path", - "name": "hash", - "required": true, - "schema": { - "type": "string" - } - }, - { - "explode": false, - "in": "query", - "name": "page", - "schema": { - "default": 1, - "format": "int64", - "type": "integer" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "default": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ErrorModel" - } - } - }, - "description": "Error" - } - }, - "summary": "Delete a row", - "tags": ["rows"] - } - } - } -} diff --git a/frontend/pnpm-workspace.yaml b/frontend/pnpm-workspace.yaml new file mode 100644 index 0000000..99cceb0 --- /dev/null +++ b/frontend/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +allowBuilds: + '@swc/core': true + esbuild: true From ce355d4304e1dba4cbfa20356608aeaadfa68782 Mon Sep 17 00:00:00 2001 From: Avisek Date: Sat, 9 May 2026 08:37:44 +0530 Subject: [PATCH 4/5] feat: add step to generate OpenAPI schema in CI workflow --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 14e9cee..79f2bd6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -93,6 +93,9 @@ jobs: node-version: 24 cache: "pnpm" + - name: generate openapi schema + run: go run ./cmd/schema/main.go + - name: Run go generate run: go generate ./... From 0b623f89ebee1095c06f001af32661d9ff15ddb6 Mon Sep 17 00:00:00 2001 From: Avisek Date: Sat, 9 May 2026 08:48:10 +0530 Subject: [PATCH 5/5] feat: abstract workspace preparation into a reusable composite action --- .github/actions/prepare/action.yml | 17 +++++++++++++++++ .github/workflows/ci.yml | 17 ++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) create mode 100644 .github/actions/prepare/action.yml diff --git a/.github/actions/prepare/action.yml b/.github/actions/prepare/action.yml new file mode 100644 index 0000000..26c8d20 --- /dev/null +++ b/.github/actions/prepare/action.yml @@ -0,0 +1,17 @@ +name: Prepare Go workspace +description: Creates embed dir, generates OpenAPI schema, and runs go generate + +runs: + using: composite + steps: + - name: Prepare embed directory + run: mkdir -p frontend/dist && touch frontend/dist/.keep + shell: bash + + - name: generate openapi schema + run: go run ./cmd/schema/main.go + shell: bash + + - name: Run go generate + run: go generate ./... + shell: bash diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 79f2bd6..ecc9e1e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,14 +30,8 @@ jobs: node-version: 24 cache: "pnpm" - - name: Prepare embed directory - run: mkdir -p frontend/dist && touch frontend/dist/.keep - - - name: generate openapi schema - run: go run ./cmd/schema/main.go - - - name: Run go generate - run: go generate ./... + - name: Prepare workspace + uses: ./.github/actions/prepare - name: Golangci Lint uses: golangci/golangci-lint-action@v9 @@ -93,11 +87,8 @@ jobs: node-version: 24 cache: "pnpm" - - name: generate openapi schema - run: go run ./cmd/schema/main.go - - - name: Run go generate - run: go generate ./... + - name: Prepare workspace + uses: ./.github/actions/prepare - name: Run go test run: go test ./...