Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
523fe4b
Complete UI overhaul. Moving from template based webui to a react com…
Jordonh18 Jan 19, 2026
aa8f5bd
feat: Add printer editing functionality and improve UI for discovered…
Jordonh18 Jan 19, 2026
e5252c2
feat: enhance UsersPage with edit/delete icons and update User type d…
Jordonh18 Jan 20, 2026
2e4c831
Refactor PrinterDetailPage and SettingsPage; add SetupPage and API to…
Jordonh18 Jan 20, 2026
a860e08
feat: Implement rate limiting for API endpoints and enhance database …
Jordonh18 Jan 20, 2026
79fbd32
feat: Add notification preferences to user model, improve notificatio…
Jordonh18 Jan 20, 2026
646f836
feat: Enhance authentication handling by allowing JWT or API token vi…
Jordonh18 Jan 21, 2026
dd4d4f3
feat: add workflow editor and management features
Jordonh18 Jan 21, 2026
225adc6
feat: Implement workflow scheduler service with APScheduler
Jordonh18 Jan 21, 2026
6bd93ff
feat: Add workflow variables documentation and VariablePicker component
Jordonh18 Jan 21, 2026
71712e5
feat: Improve option key generation in VariablePicker and WorkflowEdi…
Jordonh18 Jan 22, 2026
a8bb81a
feat: Update workflow management and API endpoints
Jordonh18 Jan 23, 2026
6d04193
feat: enhance WorkflowsPage styling and add network-related API types
Jordonh18 Jan 23, 2026
e4f3704
Rename project from Printer Proxy to Continuum, updating all relevant…
Jordonh18 Jan 23, 2026
6d13222
Refactor updater module and implement API token management
Jordonh18 Jan 23, 2026
6abbffe
fix: update issue report link to reflect project name change
Jordonh18 Jan 23, 2026
793995e
chore: remove base.html template file
Jordonh18 Jan 23, 2026
9a8065f
refactor: update project references from Printer Proxy to Continuum i…
Jordonh18 Jan 23, 2026
e64afa0
fix: revert version number to 1.1.0-alpha1 in version.py
Jordonh18 Jan 23, 2026
3eef451
fix: revert version number to 1.1.0-alpha1 in changelog
Jordonh18 Jan 23, 2026
0d42e3f
docs: enhance README with detailed features, installation, and develo…
Jordonh18 Jan 23, 2026
82f6956
feat: add PR checks workflow for versioning, building, and testing pa…
Jordonh18 Jan 23, 2026
e0badae
fix: update import path for init_db in __init__.py and adjust PR perm…
Jordonh18 Jan 23, 2026
1d8848f
fix: correct application files path in continuum.install
Jordonh18 Jan 23, 2026
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
96 changes: 96 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: Bug Report
description: Report a bug or issue with Continuum
title: "[Bug]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to report a bug! Please fill out the information below to help us investigate.

- type: textarea
id: description
attributes:
label: Description
description: A clear description of what the bug is
placeholder: What went wrong?
validations:
required: true

- type: textarea
id: steps
attributes:
label: Steps to Reproduce
description: Steps to reproduce the behavior
placeholder: |
1. Go to '...'
2. Click on '...'
3. See error
validations:
required: true

- type: textarea
id: expected
attributes:
label: Expected Behavior
description: What you expected to happen
validations:
required: true

- type: textarea
id: actual
attributes:
label: Actual Behavior
description: What actually happened
validations:
required: true

- type: input
id: version
attributes:
label: Continuum Version
description: What version are you running?
placeholder: e.g., 2.0.0
validations:
required: true

- type: dropdown
id: install_method
attributes:
label: Installation Method
description: How did you install Continuum?
options:
- APT repository
- Manual .deb package
- From source
validations:
required: true

- type: textarea
id: environment
attributes:
label: Environment
description: Information about your system
placeholder: |
- OS: Ubuntu 22.04
- Python version: 3.11
- Network interface: eth0
validations:
required: false

- type: textarea
id: logs
attributes:
label: Relevant Logs
description: Paste any relevant log output here (check /var/log/continuum/ or `sudo journalctl -u continuum`)
render: shell
validations:
required: false

- type: textarea
id: additional
attributes:
label: Additional Context
description: Any other context about the problem
validations:
required: false
8 changes: 8 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
blank_issues_enabled: true
contact_links:
- name: Documentation
url: https://github.com/Jordonh18/continuum/wiki
about: Check the documentation for help and guides
- name: Discussions
url: https://github.com/Jordonh18/continuum/discussions
about: Ask questions and discuss ideas with the community
63 changes: 63 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Feature Request
description: Suggest a new feature or enhancement for Continuum
title: "[Feature]: "
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Thanks for suggesting a feature! Please describe what you'd like to see added to Continuum.

- type: textarea
id: problem
attributes:
label: Problem Statement
description: What problem does this feature solve? Is your feature request related to a problem?
placeholder: I'm always frustrated when...
validations:
required: true

- type: textarea
id: solution
attributes:
label: Proposed Solution
description: Describe the solution you'd like to see
placeholder: I'd like to be able to...
validations:
required: true

- type: textarea
id: alternatives
attributes:
label: Alternatives Considered
description: Have you considered any alternative solutions or workarounds?
validations:
required: false

- type: dropdown
id: component
attributes:
label: Related Component
description: Which part of Continuum does this relate to?
options:
- Printer Management
- Network/Redirects
- Health Monitoring
- Job Tracking
- Workflows/Automation
- Web UI
- API
- Authentication
- Notifications
- System/Installation
- Other
validations:
required: false

- type: textarea
id: additional
attributes:
label: Additional Context
description: Any other context, screenshots, or examples about the feature request
validations:
required: false
28 changes: 19 additions & 9 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
# Copilot Instructions for Printer Proxy
# Copilot Instructions for Continuum

## Project Overview

Printer Proxy is a Flask web application that redirects network print traffic via NAT/iptables. When a printer fails, clients continue printing to the same IP while traffic is forwarded to a working printer.
Continuum is a Flask + React web application that redirects network print traffic via NAT/iptables. When a printer fails, clients continue printing to the same IP while traffic is forwarded to a working printer.

## Architecture

### Core Components

- **Flask App Factory**: [app/__init__.py](app/__init__.py) - Uses `create_app()` pattern with blueprints (`main_bp`, `auth_bp`, `api_bp`)
- **Routes**: [app/routes.py](app/routes.py) - All web routes and API endpoints
- **Flask App Factory**: [app/__init__.py](app/__init__.py) - Uses `create_app()` pattern with `api_bp` blueprint
- **React Frontend**: [frontend/](frontend/) - Vite + React + TypeScript SPA with Tailwind CSS
- **API Routes**: [app/routes.py](app/routes.py) - JSON API endpoints only (no templates)
- **Models**: [app/models.py](app/models.py) - SQLite database with raw SQL (no ORM)
- **Network Manager**: [app/network.py](app/network.py) - Calls privileged bash helper via sudo
- **Network Helper**: [scripts/network_helper.sh](scripts/network_helper.sh) - Bash script for iptables/NAT operations (runs as root)

### Frontend Stack

- **React 18** with TypeScript
- **Vite** for build tooling
- **Tailwind CSS** for styling
- **TanStack Query** for data fetching
- **React Router DOM** for client-side routing
- **JWT Authentication** via flask-jwt-extended

### Data Flow for Redirects

1. User creates redirect via web UI → [app/routes.py](app/routes.py#L126)
1. User creates redirect via React UI → API call to `/api/redirects`
2. `NetworkManager` calls `network_helper.sh` via sudo
3. Helper script adds secondary IP + NAT rules with iptables
4. Print traffic to broken IP is forwarded to target printer
Expand Down Expand Up @@ -75,15 +85,15 @@ Uses mDNS (zeroconf) and SNMP scanning. See [app/discovery.py](app/discovery.py)

### Authentication

Flask-Login with bcrypt password hashing. Account lockout after failed attempts. See [app/auth.py](app/auth.py).
JWT tokens for API authentication via flask-jwt-extended. Bcrypt password hashing. Account lockout after failed attempts. See [app/auth.py](app/auth.py).

## File Locations (Production)

| Path | Purpose |
|------|---------|
| `/opt/printer-proxy/` | Application code |
| `/var/lib/printer-proxy/` | SQLite database, secrets |
| `/var/log/printer-proxy/` | Application logs |
| `/opt/continuum/` | Application code |
| `/var/lib/continuum/` | SQLite database, secrets |
| `/var/log/continuum/` | Application logs |

Config auto-detects install vs development mode in [config/config.py](config/config.py#L82).

Expand Down
140 changes: 140 additions & 0 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
name: PR Checks

on:
pull_request:
branches: [main]
paths-ignore:
- 'README.md'
- 'docs/**'
- '.github/copilot-instructions.md'
- 'LICENSE'
- '*.md'
- '.gitignore'

permissions:
contents: read
pull-requests: write

concurrency:
group: pr-checks-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
check-version:
name: Check Version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Get version
id: version
run: |
VERSION=$(python3 -c "exec(open('app/version.py').read()); print(__version__)")
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version: $VERSION"

build:
name: Build Package
runs-on: ubuntu-latest
needs: check-version

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install build dependencies
run: sudo apt-get update && sudo apt-get install -y dpkg-dev fakeroot gzip

- name: Build .deb package
run: |
chmod +x scripts/build-deb.sh
./scripts/build-deb.sh

- name: Verify package
run: |
VERSION="${{ needs.check-version.outputs.version }}"
DEB_FILE="builds/continuum_${VERSION}_all.deb"

if [ ! -f "$DEB_FILE" ]; then
echo "ERROR: Package not built"
exit 1
fi

dpkg-deb --info "$DEB_FILE"
cd builds && sha256sum -c "continuum_${VERSION}_all.deb.sha256"

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: debian-package
path: |
builds/*.deb
builds/*.sha256
retention-days: 7

test:
name: Test Installation
runs-on: ubuntu-latest
needs: [check-version, build]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: debian-package
path: builds/

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y python3 python3-venv python3-pip \
iptables iproute2 iputils-ping arping nginx openssl

- name: Test installation
run: |
VERSION="${{ needs.check-version.outputs.version }}"
sudo dpkg -i "builds/continuum_${VERSION}_all.deb" || sudo apt-get install -f -y

- name: Verify installation
run: |
[ -d "/opt/continuum" ] && echo "OK: App directory exists"
[ -d "/opt/continuum/venv" ] && echo "OK: Virtual environment created"
[ -f "/lib/systemd/system/continuum.service" ] && echo "OK: Service installed"

cd /opt/continuum
sudo -u continuum /opt/continuum/venv/bin/python -c "from app import create_app; print('Imports OK')"

- name: Comment on PR
uses: actions/github-script@v7
if: always()
with:
script: |
const status = '${{ job.status }}';
const version = '${{ needs.check-version.outputs.version }}';
const icon = status === 'success' ? '✅' : '❌';

const body = `## ${icon} Build & Test ${status === 'success' ? 'Passed' : 'Failed'}

**Version:** \`${version}\`
**Package:** \`continuum_${version}_all.deb\`

${status === 'success' ? 'All checks passed! Ready to merge.' : 'Some checks failed. Please review the logs.'}`;

github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
Loading
Loading