Skip to content

Latest commit

 

History

History
404 lines (307 loc) · 17.3 KB

File metadata and controls

404 lines (307 loc) · 17.3 KB

Contributing to LinaPro

English | 简体中文

Thank you for your interest in contributing to LinaPro. This guide explains the project context, development environment, workflow, and contribution requirements.

Project Overview

LinaPro is an AI-native full-stack framework for sustainable delivery. It treats AI as a core productivity engine: AI leads analysis, design, and implementation, while the team controls direction and key decisions.

LinaPro brings backend services, a frontend workspace, a pluggable plugin system, and a specification-driven AI development workflow into one full-stack delivery framework. It includes a ready-to-use default management workspace with common business-system capabilities such as permission management, system configuration, and job scheduling, so new projects can start business development without rebuilding foundational infrastructure.

  • Frontend: Vben5 + Vue 3 + Ant Design Vue + TypeScript
  • Backend: GoFrame + PostgreSQL + JWT + source/WASM plugin runtime
  • Development workflow: SDD + OpenSpec

Default Account

  • Username: admin
  • Password: admin123

Repository Layout

apps/                -> Monorepo project directory
  lina-core/         -> Core host service for the full-stack framework (GoFrame)
    api/             -> Request/response DTOs (g.Meta route definitions)
    internal/        -> Core backend implementation
      cmd/           -> Service startup and route registration
      controller/    -> HTTP controllers (scaffolded by make ctrl)
      dao/           -> Data access layer (generated by make dao)
      model/         -> Data models
        do/          -> Data operation objects (generated)
        entity/      -> Database entities (generated)
      service/       -> Business logic layer
    manifest/        -> Delivery manifest
      config/        -> Backend configuration files
      sql/           -> DDL + seed DML (versioned SQL files)
        mock-data/   -> Mock demo/test data (not deployed to production)
  lina-vben/         -> Default management workspace (Vben5 frontend pnpm monorepo)
    apps/web-antd/   -> Default management workspace application (Ant Design Vue)
    packages/        -> Shared libraries (@core, effects, stores, utils, and more)
  lina-plugins/      -> Official source plugin repository submodule mount point
    <plugin-id>/     -> Source plugin directory (standard structure)
      backend/       -> Plugin backend entry and implementation
        api/         -> Plugin API DTOs and route definitions
        internal/    -> Plugin backend internal implementation
          controller/ -> HTTP controllers
          service/    -> Business logic layer
          dao/        -> Data access layer (generated by make dao when needed)
          model/      -> Data models (generated when needed)
            do/       -> Data operation objects (generated)
            entity/   -> Database entities (generated)
        hack/        -> Plugin codegen and development config, such as hack/config.yaml
        plugin.go    -> Plugin backend registration entry
      frontend/      -> Plugin frontend pages and assets
      manifest/      -> Plugin installation, uninstall, and delivery resources
      hack/          -> Plugin development and test resources
        tests/
          e2e/       -> Plugin-owned TC test cases
          pages/     -> Plugin-owned E2E page objects
          support/   -> Plugin-owned E2E helpers
      plugin.yaml    -> Plugin manifest
      plugin_embed.go -> Plugin embedded resource entry
hack/                -> Project scripts and test files
  tests/             -> Host and shared E2E tests (Playwright)
    e2e/             -> Host TC test cases; source plugin E2E belongs in plugin directories
    fixtures/        -> Test fixtures (auth, config)
    pages/           -> Host/shared page object models
openspec/            -> OpenSpec documents
  changes/           -> OpenSpec change records

Common Commands

Development Environment

make dev                         # Start frontend and backend (frontend: 5666, backend: 9120)
make dev plugins=0               # Force host-only mode without official source plugins
make stop                        # Stop all services
make status                      # Check service status
make dev.setup                  # Install frontend deps + Playwright browsers (first time only)
make test                        # Run the full E2E suite
make db.init                     # Initialize the database (DDL + seed data)
make db.mock                     # Load mock demo data; run db.init first
make image tag=v0.6.0            # Build the production Docker image
make release.tag.check tag=v0.6.0 # Verify the release tag matches metadata.yaml framework.version
make up                          # Generate a commit message with claude and push by default
make up tool=codex               # Generate a commit message with codex and push
make up t=codex                  # Short alias for tool=codex
make up tool=codex               # Codex default model is gpt-5.1-codex-mini
make up tool=codex model=gpt-5.2 # Specify AI tool and model; m=... is also supported

When apps/lina-plugins contains plugin manifests, make image automatically enables plugin-full mode. Add registry=ghcr.io/linaproai push=1 to build and push an image.

Backend

cd apps/lina-core
go run main.go          # Run the backend
make build              # Build
make dao                # Generate DAO/DO/Entity after SQL changes
make ctrl               # Generate controller scaffolding after API definition changes

Frontend

cd apps/lina-vben
pnpm install                   # Install dependencies
pnpm -F @lina/web-antd dev     # Start development mode
pnpm run build                 # Build

E2E Tests

Install frontend dependencies and Playwright browsers before the first run:

make dev.setup
cd hack/tests
pnpm test              # Run all tests
pnpm test:headed       # Run with a visible browser
pnpm test:ui           # Open the interactive test UI
pnpm test:debug        # Debug tests
pnpm report            # View the HTML report

Test files must use the TC{NNNN}*.ts naming format, such as TC0001-login.ts. Host tests belong under hack/tests/e2e/ by module. Source plugin tests belong under apps/lina-plugins/<plugin-id>/hack/tests/e2e/, and plugin-owned page objects and helpers belong under the same plugin's hack/tests/pages/ and hack/tests/support/ directories.

Official Plugin Workspace

  • Official source plugins are maintained independently at https://github.com/linaproai/official-plugins.git.
  • The main repository mounts the official plugin repository through the apps/lina-plugins submodule.
  • Host-only commands can run before the submodule is initialized.
  • make dev, make build, make image, and make image.build automatically detect apps/lina-plugins/*/plugin.yaml when plugins is not explicitly set. If plugin manifests exist, plugin-full mode is enabled; otherwise host-only mode is used. Pass plugins=0 to force host-only mode.
  • Plugin-full mode generates or refreshes the ignored temp/go.work.plugins file from the host-only root go.work, then resolves source plugin Go modules through GOWORK. The root go.work always remains host-only.
  • Plugin-owned tests and plugin E2E require git submodule update --init --recursive.
  • The local submodule remote uses git@github.com:linaproai/official-plugins.git.

Getting Started

Prerequisites

Tool Version Purpose
Go 1.25.0+ Backend development
Node.js 22+ Frontend development
pnpm 10+ Frontend package manager
PostgreSQL 14+ Default database
make any Compatibility task runner

Quick Setup

# 1. Fork the repository and clone your fork
git clone https://github.com/<your-username>/linapro.git
cd linapro

# 2. Initialize the official plugins workspace when you need plugin-full mode
git submodule update --init --recursive

# 3. Initialize the database (DDL + seed data)
make db.init

# 4. Start the full stack (frontend: 5666, backend: 9120)
make dev

Development Workflow

LinaPro uses the OpenSpec specification-driven workflow. Every non-trivial contribution must follow this five-stage cycle:

Explore -> Propose -> Implement -> Review -> Archive
Stage Command Output
Explore /opsx:explore Shared understanding of the problem and solution space
Propose /opsx:propose <feature-name> openspec/changes/<feature>/ with proposal.md, design.md, specs/, and tasks.md
Implement /opsx:apply Code, tests, and documentation aligned to tasks.md
Review /lina-review Automated review of code quality and spec compliance
Archive /opsx:archive Change moved to openspec/changes/archive/

For simple, isolated bug fixes, you may skip Explore and Propose and jump directly to Implement, but all changes must pass Review before merging.

Making Changes

Backend (lina-core)

The backend uses GoFrame. Generated files must never be edited by hand.

cd apps/lina-core

# After modifying api/{resource}/v1/*.go
make ctrl

# After adding or modifying manifest/sql/*.sql
make db.init
make dao

Key rules:

  • Business errors returned to callers must be wrapped with pkg/bizerr.
  • Use pkg/logger for all logging, and never call g.Log() directly.
  • Always pass ctx context.Context through the full call chain.
  • All error return values must be explicitly handled.
  • Enumerations must be declared as named Go types with constants; do not use bare string literals in business logic.

Frontend (lina-vben)

cd apps/lina-vben
pnpm install
pnpm -F @lina/web-antd dev

Key rules:

  • Use useVbenForm for forms, useVbenModal for modals, and useVbenDrawer for drawers.
  • Use useVbenVxeGrid with Page for table pages; operation buttons use ghost-button and Popconfirm.
  • Icons use IconifyIcon from @vben/icons with Iconify format names, such as ant-design:inbox-outlined.
  • Path alias #/* resolves to ./src/*.
  • Check the reference project for UI and interaction patterns before implementing new pages.

Plugin Development

Plugins live under apps/lina-plugins/<plugin-id>/ and must include:

<plugin-id>/
  plugin.yaml         -> Plugin manifest
  plugin_embed.go     -> Embedded resource entry
  backend/
    api/              -> Plugin API DTOs and route definitions
    plugin.go         -> Plugin registration entry
    internal/
      controller/     -> HTTP controllers
      service/        -> Business logic
      dao/            -> Generated DAO when database access is needed
      model/          -> Generated models
    hack/config.yaml  -> Codegen configuration
  frontend/pages/     -> Plugin frontend pages
  manifest/
    sql/              -> Install SQL
    sql/uninstall/    -> Uninstall SQL
    i18n/             -> Plugin i18n resources

Plugin business logic belongs in backend/internal/service/. Only provider or adapter implementations of stable host extension seams belong in backend/provider/.

Commit Guidelines

Use Conventional Commits:

<type>(<scope>): <short summary>
Type When to use
feat New feature or capability
fix Bug fix
docs Documentation-only changes
refactor Code restructuring with no behavior change
test Adding or updating tests
chore Build scripts, CI, dependencies
perf Performance improvement

Examples:

feat(plugin): add WASM sandbox memory limit configuration
fix(auth): prevent session token from persisting after force-logout
docs(contributing): add plugin workspace commands

Keep the summary line under 72 characters. Add a blank line before any extended description.

Pull Request Process

  1. Fork the repository and create a branch from main:

    git checkout -b feat/my-feature
  2. Follow the OpenSpec workflow for non-trivial changes. Attach or reference the relevant openspec/changes/<feature>/ artifacts in your pull request description.

  3. Ensure all checks pass before requesting review:

    make test
  4. Open a pull request against main with a clear title, a summary of what changed and why, links to related issues or OpenSpec change documents, and screenshots or screen recordings for UI changes.

  5. At least one maintainer approval is required before merging.

Release Tags

Release tag names must match apps/lina-core/manifest/config/metadata.yaml framework.version exactly. Maintainers should check the target version locally before releasing:

make release.tag.check tag=v0.2.0

Use the Create Release Tag GitHub Actions workflow for normal releases. The workflow reads framework.version, validates it through linactl release.tag.check, refuses to move an existing tag, and creates the matching Git tag.

Repository maintainers should configure a GitHub tag ruleset for release tags such as v*. The ruleset should block direct creation, updates, and deletion by ordinary users, then allow only the controlled release actor to bypass the rule.

The controlled workflow creates a short-lived GitHub App installation token from repository variable RELEASE_APP_CLIENT_ID and repository secret RELEASE_APP_PRIVATE_KEY. The GitHub App must be installed on this repository and have Contents read/write permission.

Ruleset bypass is granted to actors, not to token strings. Add the GitHub App used by the controlled workflow to the release tag ruleset bypass list. Tags pushed with the default GITHUB_TOKEN do not reliably trigger another workflow run, so the controlled workflow uses the GitHub App token to let the tag push trigger the downstream release workflow.

Coding Standards

Go

  • All source files must have a package-level comment in the main file or a file-level comment in other files.
  • Time durations use time.Duration in code and unit-suffixed strings, such as "10s" and "5m", in configuration.
  • Multi-step database operations use dao.Xxx.Transaction() closures.
  • Use database-agnostic ORM constructs. Do not use database-specific functions such as FIND_IN_SET, GROUP_CONCAT, or ANY(ARRAY[...]).
  • DAO, DO, and Entity files are generated by make dao; never edit them manually.
  • Controller files are scaffolded by make ctrl; fill in business logic only and do not change the generated skeleton.

TypeScript / Vue 3

  • Follow the project's ESLint and Prettier configuration.
  • Keep component files focused: one component per file.
  • Use TypeScript strict mode and avoid any.
  • API calls go in src/api/ using the project's requestClient.
  • i18n keys follow the module.subkey convention; never hard-code user-visible strings.

Testing

E2E Tests (Playwright)

All user-observable behavior changes must be covered by E2E tests.

Install frontend dependencies and Playwright browsers before the first run:

make dev.setup
cd hack/tests
pnpm test              # Run the full suite in headless mode
pnpm test:headed       # Run with a visible browser
pnpm test:ui           # Open the interactive Playwright UI
pnpm report            # View the HTML report

Test file naming: TC{NNNN}-<description>.ts, such as TC0042-user-batch-export.ts, placed in hack/tests/e2e/ under the relevant module directory.

Each test file should cover the complete operation set for its feature, such as list, create, edit, delete, and any special actions. Files generated during testing, including screenshots and downloads, go in the project root temp/ directory.

i18n Guidelines

LinaPro supports multiple languages. Every contribution must evaluate i18n impact:

  • New user-visible strings must have corresponding entries in all supported language files.
  • Frontend runtime translations live in apps/lina-vben/ locale packages.
  • Host API documentation translations live in apps/lina-core/manifest/i18n/<locale>/apidoc/.
  • Plugin translations are self-contained in apps/lina-plugins/<plugin-id>/manifest/i18n/.
  • Never hard-code user-visible text in Go or TypeScript source. Always use an i18n key.
  • en-US apidoc files contain only empty object placeholders; the English source is the API DTO itself.

If a change does not affect i18n resources, state this explicitly in your pull request description.

Community

Channel Link
GitHub Issues https://github.com/linaproai/linapro/issues
Website https://linapro.ai/
Live Demo http://demo.linapro.ai/

Please search existing issues before opening a new one. For security vulnerabilities, do not open a public issue; contact the maintainers directly.