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
16 changes: 16 additions & 0 deletions AI-prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Build an x0 application using the x0 framework from https://github.com/WEBcodeX1/x0,
The backend in Python should use the https://github.com/clauspruefer/python-micro-esb project
The CSS styling is done with the x0 contained Bootstrap default theme and should look modern.
The browser-frontend consists of 3 x0 screens / 3 menu entries:
1. Screen1 "User Credentials": contains 2 groups of formfields (x0 object of type `sysObjectFormfieldList`): group a) GitHub API User/Token credentials group b) Stackfield API User/Token Credentials
1.1. On each formfield group there must be a button "verify user credentials" to test if the API authentication is working
2. Screen2 "Issue / Task Mapping": contains the mapping between GitHub Issues and Stackfield Tasks
2.1. On top there should be 1 formfield / search input and a search execution button (x0 object of type `sysObjectFormfieldList`)
2.2. Under the search must be a list (x0 object of type `sysObjectList` containing the search results
2.3. The search result list from 2.2. contains a x0 object of type `sysObjContextMenu` with one entry "Connect Stackfield Task"
2.4. On button click from 2.1 the relevant python-micro-esb backend service must be called and the given result list from 2.2 must be filled with the result data from the backend service
3. Screen3 "Connect Stackfield Task"
3.1. Contains detailed GitHub Task properties from GitHub API webservice result (encapsulated from python-micro-esb backend), e.g. 3 or four formfields describing the task properties from API result
3.2. On right click of screen 2 object result display list single row, the GitHub task properties fields of Screen3 will be updated from the row data
3.3. Also there should be relevant Stackfield properties where to map the Stackfield Task (Stackfield room or similar, please find the best possible fields from the API to map)
3.4. At the bottom there must be 1 button (x0 object type `sysObjButton`), on click a NEW STACKFIELD TASK will be generated from the relevant GitHub Issue/Task data from Screen3 formfield data.
141 changes: 141 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# github2stackfield

**github2stackfield** is an x0 web application that bridges **GitHub Issues** with **Stackfield Tasks**.
It lets you search GitHub issues, inspect their details, and create corresponding Stackfield tasks — all from a clean, Bootstrap-styled browser frontend.

---

## Architecture

| Layer | Technology |
|---|---|
| Browser frontend | [x0 JavaScript framework](https://github.com/WEBcodeX1/x0) with Bootstrap default theme |
| Backend services | Python WSGI scripts via [python-micro-esb](https://github.com/clauspruefer/python-micro-esb) |
| Database | PostgreSQL (shared x0 instance) |
| Deployment | Apache2 + mod_wsgi (Docker or bare-metal) |

---

## Screens

### Screen 1 — User Credentials
Configure and verify API access for both platforms.

- **GitHub API Credentials** — enter your GitHub username and Personal Access Token.
Click *Verify GitHub Credentials* to validate and store them.
- **Stackfield API Credentials** — enter your Stackfield e-mail and API token.
Click *Verify Stackfield Credentials* to validate and store them.

### Screen 2 — Issue / Task Mapping
Search GitHub issues and select one to map to Stackfield.

1. Enter the target repository (`owner/repository`) and an optional search term.
2. Click **Search Issues** — results populate the issue list below.
3. Right-click any row and select **Connect Stackfield Task** to navigate to Screen 3.

### Screen 3 — Connect Stackfield Task
Review the selected GitHub issue and create a Stackfield task.

- **GitHub Issue Properties** — read-only fields: issue number, state, title, URL.
- **Stackfield Task Mapping** — editable fields pre-populated from the issue:
- *Stackfield Room ID* — the target Stackfield room / channel identifier.
- *Task Title* — editable, defaults to the GitHub issue title.
- *Description* — editable, defaults to the GitHub issue body.
- *Priority* — Low / Medium / High / Urgent.
- Click **Create New Stackfield Task** — a new task is created in Stackfield via the REST API.

---

## Prerequisites

| Requirement | Notes |
|---|---|
| Docker Engine | With Compose V2 (`docker compose`) |
| GitHub Personal Access Token | Needs `repo` scope for private repos, `public_repo` for public |
| Stackfield API token | See Stackfield workspace settings → Integrations → API |

---

## Docker (quick start)

The application uses the official x0 container images:

- **`ghcr.io/webcodex1/x0-app`** — Apache2 + mod_wsgi web application server with the x0 JavaScript framework pre-installed ([packages page](https://github.com/WEBcodeX1/x0/pkgs/container/x0-app))
- **`ghcr.io/webcodex1/x0-db`** — PostgreSQL 16 database with the x0 schema pre-installed ([packages page](https://github.com/WEBcodeX1/x0/pkgs/container/x0-db))

Both custom images are built automatically on `docker compose up --build`:

- `docker/Dockerfile` extends `ghcr.io/webcodex1/x0-app` and copies all static files, Python WSGI scripts, and the Apache2 config snippet into the image.
- `docker/Dockerfile.db` extends `ghcr.io/webcodex1/x0-db` and runs the github2stackfield SQL init scripts (`database/0*.sql`) against the x0 database on first start.

```bash
cd docker
docker compose up --build
```

Then open [http://localhost:8080/?appid=github2sf](http://localhost:8080/?appid=github2sf).

No further manual configuration is required.

---

## Project structure

```
github2stackfield/
├── static/
│ ├── menu.json # x0 navigation menu definition
│ ├── object.json # x0 UI objects (formfields, lists, buttons …)
│ └── skeleton.json # x0 screen layout
├── python/
│ ├── service_implementation.py # GitHubService + StackfieldService ClassHandlers
│ ├── user_routing.py # python-micro-esb ServiceRouter routing functions
│ ├── VerifyGitHubCredentials.py # WSGI – verify GitHub credentials
│ ├── VerifyStackfieldCredentials.py # WSGI – verify Stackfield credentials
│ ├── SearchGitHubIssues.py # WSGI – search issues, populate list
│ ├── GetGitHubIssueDetails.py # WSGI – fetch issue details for Screen 3
│ ├── CreateStackfieldTask.py # WSGI – create Stackfield task
│ ├── POSTData.py # x0 POST body reader helper
│ └── StdoutLogger.py # logging helper
├── database/
│ ├── 01-create-schema.sql # github2sf schema + tables
│ ├── 02-insert-config.sql # x0 app configuration rows
│ └── 03-insert-text.sql # UI text / i18n entries
├── docker/
│ ├── Dockerfile # extends x0-app, bakes in static/ python/ apache2.conf
│ ├── Dockerfile.db # extends x0-db, auto-inits github2sf schema on startup
│ ├── docker-compose.yml
│ ├── db-init.sh # startup script used by Dockerfile.db
│ └── apache2.conf
└── README.md
```

---

## python-micro-esb integration

The backend services are built on the [python-micro-esb](https://github.com/clauspruefer/python-micro-esb) framework:

- **`service_implementation.py`** — contains `GitHubService` and `StackfieldService`, both subclassing `microesb.ClassHandler`. Each class exposes service methods (`verify`, `search_issues`, `get_issue_details`, `create_task`).
- **`user_routing.py`** — routing functions consumed by `ServiceRouter.send()`. Each function instantiates the appropriate service class, calls the relevant method, and returns the result.
- **WSGI scripts** — thin wrappers that read the x0 POST payload, call `ServiceRouter.send()`, and return JSON to the x0 frontend.

---

## Stackfield API notes

Stackfield's REST API is available at `https://www.stackfield.com/api/v1/`.
Key endpoints used:

| Endpoint | Purpose |
|---|---|
| `GET /v1/user` | Verify credentials |
| `POST /v1/rooms/{room_id}/tasks` | Create a new task |

The **Room ID** can be found in Stackfield under *Room settings → General → Room ID* or via the URL slug.

---

## License

See [LICENSE](LICENSE).
59 changes: 59 additions & 0 deletions database/01-create-schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
-- ]*[ ------------------------------------------------------------------ ]*[
-- . github2stackfield - Database Schema .
-- ]*[ ------------------------------------------------------------------ ]*[
-- . .
-- . Run against an existing x0 PostgreSQL database. .
-- . The x0 framework must be set up first (see x0 repository). .
-- . .
-- ]*[ ------------------------------------------------------------------ ]*[

-- Application schema
CREATE SCHEMA IF NOT EXISTS github2sf;

-- ---------------------------------------------------------------------------
-- API Credentials storage
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS github2sf.credentials (
credential_type VARCHAR(20) NOT NULL,
username_or_email TEXT NOT NULL,
api_token TEXT NOT NULL,
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
CONSTRAINT pk_credentials PRIMARY KEY (credential_type)
Comment on lines +16 to +21
);

COMMENT ON TABLE github2sf.credentials IS
'Stores GitHub and Stackfield API credentials (one row per credential_type).';

-- ---------------------------------------------------------------------------
-- Application configuration key-value store
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS github2sf.app_config (
config_key VARCHAR(100) NOT NULL,
value TEXT,
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
CONSTRAINT pk_app_config PRIMARY KEY (config_key)
);

COMMENT ON TABLE github2sf.app_config IS
'Key-value store for github2stackfield application runtime configuration.';

-- ---------------------------------------------------------------------------
-- Issue / Task mapping log
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS github2sf.issue_task_mapping (
id SERIAL NOT NULL,
github_repo TEXT NOT NULL,
github_issue_number INTEGER NOT NULL,
github_issue_title TEXT,
stackfield_room_id TEXT NOT NULL,
stackfield_task_id TEXT,
stackfield_task_url TEXT,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
CONSTRAINT pk_issue_task_mapping PRIMARY KEY (id)
);

CREATE INDEX IF NOT EXISTS idx_issue_task_mapping_repo_issue
ON github2sf.issue_task_mapping (github_repo, github_issue_number);

COMMENT ON TABLE github2sf.issue_task_mapping IS
'Audit log of all GitHub issue → Stackfield task mappings created by the app.';
22 changes: 22 additions & 0 deletions database/02-insert-config.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-- ]*[ ------------------------------------------------------------------ ]*[
-- . github2stackfield - x0 Application Configuration .
-- ]*[ ------------------------------------------------------------------ ]*[
-- . .
-- . Insert the x0 system.config rows for the github2stackfield app. .
-- . Adjust app_id value if your x0 setup uses a different identifier. .
-- . .
-- ]*[ ------------------------------------------------------------------ ]*[

-- Remove any previously inserted config for this app
DELETE FROM system.config WHERE app_id = 'github2sf';

INSERT INTO system.config (app_id, config_group, "value") VALUES
('github2sf', 'index_title', 'GitHub ↔ Stackfield Connector'),
('github2sf', 'debug_level', '0'),
('github2sf', 'display_language', 'en'),
('github2sf', 'default_screen', 'Screen1'),
('github2sf', 'parent_window_url', 'null'),
('github2sf', 'subdir', '/static/github2sf'),
('github2sf', 'config_file_menu', 'menu.json'),
('github2sf', 'config_file_object', 'object.json'),
('github2sf', 'config_file_skeleton','skeleton.json');
Loading