# Deepin UOS Store Debian Packaging Design

## Goal

Adapt `LabelNova`'s Debian packaging to the deepin/UOS app-store layout that installs the application payload under `/opt/apps/<appid>`.

The package should still be built and uploaded through the existing Debian source-package plus OBS workflow, but its installed runtime structure must match deepin/UOS store conventions instead of a standard `/usr`-centric desktop package.

## Corrected Constraint

The key packaging constraint is:

- the effective application payload must live under `/opt/apps/<appid>`

This includes the main executable, frontend assets, desktop entries, icon assets, and app metadata used by the store/runtime integration.

The previous `/usr`-first design is therefore incorrect for this target and must not be used for implementation.

## Current State

The project currently has:

- a Qt desktop shell built with `cmake`
- standard Debian packaging through `debhelper`
- OBS source-package upload already working
- application assets currently installed with a normal Debian desktop layout

That means the current package is buildable as a Debian package, but its installation structure does not match the deepin/UOS store packaging style.

## Decision

Keep the Debian source package and OBS workflow, but switch the installed app layout to a deepin/UOS store style package rooted at `/opt/apps/<appid>`.

Use:

- Debian source and binary package name: `labelnova`
- application ID: `cn.labelnova.app`

This gives us:

- stable existing OBS package naming
- a reverse-DNS style app ID suitable for deepin/UOS layout
- a clear separation between Debian package identity and runtime app identity

## Why This Approach

This is the lowest-risk correction because it changes the installed layout without forcing a rename of the Debian package already used in OBS.

It also matches the local deepin/UOS-style package references available in this environment:

- application payload under `/opt/apps/<appid>/files`
- desktop entries under `/opt/apps/<appid>/entries/applications`
- optional autostart entries under `/opt/apps/<appid>/entries/autostart`
- application metadata stored in `/opt/apps/<appid>/info`

`LabelNova` does not need autostart or tray-agent packaging, so the store layout can stay simpler than those multi-process examples.

## Scope

In scope:

- move installed runtime payload under `/opt/apps/cn.labelnova.app/files`
- move desktop launcher metadata under `/opt/apps/cn.labelnova.app/entries`
- add the required app `info` file under `/opt/apps/cn.labelnova.app/info`
- install icon assets under the deepin/UOS `entries/icons` hierarchy
- update Debian rules so package staging is controlled explicitly by `debian/rules`
- align launcher paths and runtime resource lookup with the `/opt/apps` layout

Out of scope:

- renaming the Debian package from `labelnova` to `cn.labelnova.app`
- converting the package to `linglong`
- adding tray agents or autostart processes
- adding built-in update mechanisms
- redesigning the Qt application itself

## Package Identity

Two identifiers remain intentional:

- Debian package name: `labelnova`
- app ID: `cn.labelnova.app`

The app ID is the canonical runtime identity and should be used consistently in:

- `/opt/apps/cn.labelnova.app`
- `cn.labelnova.app.desktop`
- `info` metadata
- icon file naming under `entries/icons`

## Installed Layout

The final package layout should be:

- `/opt/apps/cn.labelnova.app/files/bin/labelnova`
- `/opt/apps/cn.labelnova.app/files/frontend/index.html`
- `/opt/apps/cn.labelnova.app/files/frontend/static/...`
- `/opt/apps/cn.labelnova.app/files/frontend/icons/...`
- `/opt/apps/cn.labelnova.app/entries/applications/cn.labelnova.app.desktop`
- `/opt/apps/cn.labelnova.app/entries/icons/hicolor/scalable/apps/cn.labelnova.app.svg`
- `/opt/apps/cn.labelnova.app/info`

The package may still install Debian-standard package metadata such as changelog and copyright under normal package-managed locations, but the runnable application payload must be rooted under `/opt/apps/cn.labelnova.app`.

## Runtime Layout Implications

The desktop launcher should start the app with an absolute path:

- `Exec=/opt/apps/cn.labelnova.app/files/bin/labelnova %U`

The Qt shell and frontend loading logic should work from the `/opt/apps` layout without depending on `/usr/share/labelnova`.

The current frontend discovery logic already supports a `bin -> ../frontend` relationship, so the preferred runtime structure is:

- executable in `files/bin`
- frontend assets in `files/frontend`

This keeps the runtime layout simple and avoids adding a wrapper only to remap asset paths.

## Desktop Entry Design

Add a single visible launcher at:

- `/opt/apps/cn.labelnova.app/entries/applications/cn.labelnova.app.desktop`

Required fields:

- `Type=Application`
- `Version=1.0`
- `Name=LabelNova`
- `Name[zh_CN]=LabelNova`
- `Comment=Desktop label designer with native system printing`
- `Comment[zh_CN]=支持系统打印的桌面标签设计工具`
- `Exec=/opt/apps/cn.labelnova.app/files/bin/labelnova %U`
- `Icon=cn.labelnova.app`
- `Terminal=false`
- `Categories=Graphics;Office;Utility;`
- `Keywords=label;barcode;qrcode;print;printer;`
- `Keywords[zh_CN]=标签;条码;二维码;打印;打印机;`
- `StartupNotify=true`

Vendor-specific keys such as `X-Deepin-*` should not be treated as mandatory unless store validation explicitly requires them, because we do not yet have a confirmed vendor value for this package.

## Icon Layout

Follow the deepin/UOS `entries/icons` structure rather than `/usr/share/icons` as the primary store-facing icon location.

Install:

- `/opt/apps/cn.labelnova.app/entries/icons/hicolor/scalable/apps/cn.labelnova.app.svg`

The desktop entry should reference the icon by name:

- `Icon=cn.labelnova.app`

This matches the common app-ID-based icon pattern used by `/opt/apps` packages.

## App Info Metadata

Add:

- `/opt/apps/cn.labelnova.app/info`

The file should be JSON and include at least:

- `appid`
- `name`
- `version`
- `arch`

For the first implementation:

- `appid` should be `cn.labelnova.app`
- `name` should be `LabelNova`
- `version` should be derived from the package version
- `arch` should reflect the built architecture list expected by the packaging target

Only declare permissions that the app actually needs. Since `LabelNova` does not require autostart or a tray agent, the initial design should not request those permissions.

## Debian Packaging Changes

### `debian/rules`

`debian/rules` becomes the primary owner of the deepin/UOS layout.

It should:

- build the Qt shell as it does now
- create `$(CURDIR)/debian/labelnova/opt/apps/cn.labelnova.app`
- stage `files`, `entries/applications`, and `entries/icons`
- copy the built binary into `files/bin`
- copy frontend assets into `files/frontend`
- copy the desktop entry into `entries/applications`
- copy the app icon into `entries/icons/hicolor/scalable/apps`
- generate or install the `info` file

This is closer to the local deepin/UOS examples than a declarative `debian/install`-only layout.

### `debian/install`

`debian/install` should no longer be the main driver of runtime layout.

The simplest implementation is either:

- reduce it to only package-level leftovers that still belong in standard locations
- or remove its runtime responsibilities entirely if `debian/rules` stages everything needed

The package should not keep split responsibility where some runtime files land in `/usr` and others in `/opt/apps`.

### `debian/control`

Keep:

- `Source: labelnova`
- `Package: labelnova`

Update the package description to make the `/opt/apps` delivery model explicit.

If validation tools are used, add only those that remain relevant to this packaging style. `desktop-file-utils` is still useful. AppStream tooling is no longer the primary requirement for the store layout described here.

## CMake Role

`qt-shell/CMakeLists.txt` should keep building the binary, but it should stop being treated as the source of final installed desktop metadata.

Debian packaging should own:

- final desktop entry content
- final icon placement for the store package
- final `/opt/apps` directory layout

CMake may continue to install files for generic local builds, but the Debian package output must be determined by `debian/rules`.

## Validation

Implementation is complete only when all of the following pass:

- the package stages the runnable app under `/opt/apps/cn.labelnova.app`
- the desktop entry points to `/opt/apps/cn.labelnova.app/files/bin/labelnova`
- the desktop entry references an icon that exists under `entries/icons`
- the `info` file exists and matches the chosen app ID
- Debian source-package generation still succeeds
- OBS source upload still works with the existing package name

Manual verification should cover:

- launcher visible in deepin/UOS menus
- icon resolves correctly in launcher/search results
- app starts from the desktop entry
- the app can still load its frontend assets after install
- package install and uninstall remain clean

## Risks

- resource lookup may still assume `/usr/share/labelnova`
- package scripts may accidentally leave duplicated runtime payload in both `/usr` and `/opt/apps`
- icon lookup may fail if the icon hierarchy and desktop entry naming diverge
- version or architecture fields in `info` may drift from the actual package output

Mitigation:

- make `/opt/apps/cn.labelnova.app` the only runtime payload root
- keep one canonical app ID across desktop, icon, and info files
- validate staged paths directly in the package build
- test the installed desktop launcher, not just direct binary execution

## Recommended Implementation Order

1. Add the final app ID, desktop entry, and `info` metadata files under `debian/`.
2. Rewrite `debian/rules` to stage the package under `/opt/apps/cn.labelnova.app`.
3. Move icon installation to the `entries/icons` hierarchy.
4. Remove or shrink old `/usr` runtime installation paths from Debian packaging.
5. Rebuild the Debian source package and upload a new OBS revision.
