# Work Plan: Pre-PyPI v0.1.0 Production Readiness Checklist

Created Date: 2026-03-12
Type: refactor
Estimated Duration: 1 day
Estimated Impact: 1 file (src/godotiq/license.py) + build verification
Related Issue/PR: N/A

## Related Documents
- Design Doc: N/A (production checklist, no design doc required)
- ADR: N/A
- PRD: N/A

## Objective

Ensure GodotIQ v0.1.0 is production-ready before uploading to PyPI. This is a checklist-driven effort covering debug log cleanup, cross-platform cache path handling, configuration verification, and build/test validation.

## Background

Investigation of 8 checklist items has been completed. Three items (Polar org ID, default API URL, version string) are already correct and require verification only. Two items require code changes (debug logging, cache path). Three items are build/test verification steps.

### Investigation Summary

| Check | Status | Action |
|-------|--------|--------|
| 1. Polar Production Org ID | Correct | Verify only |
| 2. Default API URL | Correct | Verify only |
| 3. Debug Logs | Needs work | Convert print() to logger, simplify messages |
| 4. License Cache Path | Needs work | Handle Windows APPDATA |
| 5. Version | Correct | Verify only |
| 6. Clean Build | Pending | Execute and verify |
| 7. Wheel Contents | Pending | Inspect and verify |
| 8. All Tests | Pending | Execute and verify |

## Risks and Countermeasures

### Technical Risks
- **Risk**: Logging change alters behavior observed by users relying on stderr output
  - **Impact**: Low -- these are debug-level messages, not part of any API contract
  - **Countermeasure**: Use standard logging module; messages remain visible via `GODOTIQ_LOG_LEVEL=INFO`

- **Risk**: Windows cache path change could break existing cache on macOS/Linux
  - **Impact**: Low -- the change only affects Windows (where `.config` was non-standard anyway); macOS/Linux path is unchanged
  - **Countermeasure**: Keep `~/.config/godotiq` as default; only use `APPDATA` on Windows when the env var exists

### Schedule Risks
- **Risk**: Unexpected test failures during final verification
  - **Impact**: Medium -- could delay PyPI upload
  - **Countermeasure**: Fix failures before proceeding; do not ship with known failures

## Phase Structure

```mermaid
graph TD
    P1[Phase 1: Code Cleanup<br/>Tasks 1-2]
    P2[Phase 2: Verification<br/>Task 3]
    P3[Phase 3: Build and Test<br/>Tasks 4-6]

    P1 --> P2
    P2 --> P3
```

## Task Dependencies

```mermaid
graph LR
    T1[Task 1: Debug log cleanup]
    T2[Task 2: Cache path fix]
    T3[Task 3: Verify checks 1,2,5]
    T4[Task 4: Clean build]
    T5[Task 5: Verify wheel]
    T6[Task 6: Run all tests]

    T1 --> T4
    T2 --> T4
    T3 --> T4
    T4 --> T5
    T4 --> T6
```

Note: Tasks 1 and 2 can run in parallel. Tasks 5 and 6 can run in parallel after Task 4.

## Implementation Phases

### Phase 1: Code Cleanup (Estimated commits: 2)
**Purpose**: Fix the two code issues identified in the investigation.

#### Tasks

- [ ] **Task 1: Clean up license.py debug logging**
  - File: `src/godotiq/license.py`
  - Lines 161 and 167: convert `print(..., file=sys.stderr)` to `logger.info()`
  - Simplify log format to: `License: key=%s -> %s` (masked key and result only)
  - Move org ID and URL detail to `logger.debug()` for troubleshooting
  - Keep existing `logger.debug()` on line 131 as-is (already appropriate)
  - Remove `import sys` if no longer used after the change
  - Completion criteria: No `print()` calls remain in `_validate_polar()`; log messages use `logger`

- [ ] **Task 2: Cross-platform cache path**
  - File: `src/godotiq/license.py`
  - Current line 71: `_CACHE_DIR = Path.home() / ".config" / "godotiq"`
  - Change to: use `os.environ.get("APPDATA")` as base on Windows, keep `~/.config/godotiq` on macOS/Linux
  - No new dependencies (no `platformdirs`)
  - Implementation approach:
    ```python
    def _cache_dir() -> Path:
        if sys.platform == "win32":
            appdata = os.environ.get("APPDATA")
            if appdata:
                return Path(appdata) / "godotiq"
        return Path.home() / ".config" / "godotiq"

    _CACHE_DIR = _cache_dir()
    ```
  - Keep `import sys` if Task 1 removed it (needed for `sys.platform`)
  - Update `_CACHE_FILE` accordingly
  - Completion criteria: `_CACHE_DIR` resolves to `%APPDATA%/godotiq` on Windows, `~/.config/godotiq` on macOS/Linux

- [ ] **Quality check: Existing tests still pass**
  - Run `pytest tests/test_license.py -v`
  - All 40+ license tests must pass (tests monkeypatch `_CACHE_DIR` and `_CACHE_FILE` so the path change is safe)

#### Phase Completion Criteria
- [ ] No `print()` calls in `_validate_polar()` -- all output via `logger`
- [ ] `_CACHE_DIR` is cross-platform aware
- [ ] `pytest tests/test_license.py -v` passes with zero failures

#### Operational Verification Procedures
1. `grep -n "print(" src/godotiq/license.py` -- should return zero matches
2. `python -c "from godotiq.license import _CACHE_DIR; print(_CACHE_DIR)"` -- verify expected path on current platform
3. `pytest tests/test_license.py -v --tb=short` -- all tests green

### Phase 2: Configuration Verification (Estimated commits: 0)
**Purpose**: Confirm the three already-correct items have not regressed.

#### Tasks

- [ ] **Task 3: Verify checks 1, 2, and 5**
  - **Check 1 -- Polar Production Org ID**:
    - Verify `_POLAR_DEFAULT_ORG_ID = "a06a7d09-881c-430d-9775-e6a7529a0831"` in `src/godotiq/license.py` line 56
    - This IS the production Polar org ID; sandbox override via `GODOTIQ_POLAR_ORG_ID` env var
    - Status: Confirmed correct
  - **Check 2 -- Default API URL**:
    - Verify `_POLAR_PROD_URL = "https://api.polar.sh/v1/customer-portal/license-keys/validate"` in `src/godotiq/license.py` line 54
    - Sandbox only activates when `GODOTIQ_POLAR_SANDBOX=true`
    - Status: Confirmed correct
  - **Check 5 -- Version**:
    - Verify `version = "0.1.0"` in `pyproject.toml` line 7
    - Verify `__init__.py` reads version dynamically via `importlib.metadata`
    - Status: Confirmed correct
  - Completion criteria: All three values verified, no changes needed

#### Phase Completion Criteria
- [ ] Org ID matches production value `a06a7d09-881c-430d-9775-e6a7529a0831`
- [ ] Default URL is `https://api.polar.sh/v1/customer-portal/license-keys/validate`
- [ ] `pyproject.toml` version is `0.1.0`

#### Operational Verification Procedures
1. `grep "_POLAR_DEFAULT_ORG_ID" src/godotiq/license.py` -- verify production org ID
2. `grep "_POLAR_PROD_URL" src/godotiq/license.py` -- verify production API URL
3. `grep 'version = ' pyproject.toml` -- verify `0.1.0`
4. `python -c "from godotiq import __version__; print(__version__)"` -- verify `0.1.0`

### Phase 3: Build, Wheel Verification, and Full Test Suite (Estimated commits: 0)
**Purpose**: Produce a clean build artifact and validate it before PyPI upload.

#### Tasks

- [ ] **Task 4: Clean build**
  - Remove stale artifacts: `rm -rf dist/ build/ *.egg-info src/*.egg-info`
  - Build: `.venv/bin/python -m build`
  - Verify both `dist/godotiq-0.1.0-py3-none-any.whl` and `dist/godotiq-0.1.0.tar.gz` are created
  - Completion criteria: Two artifacts in `dist/`, no errors during build

- [ ] **Task 5: Verify wheel contents**
  - Run: `unzip -l dist/godotiq-0.1.0-py3-none-any.whl | head -60`
  - Verify the following are included:
    - All `godotiq/*.py` modules (server.py, config.py, license.py, cli.py, __init__.py)
    - All `godotiq/parsers/*.py` modules
    - All `godotiq/tools/**/*.py` modules
    - All `godotiq/cache/*.py` modules
    - Addon files under `godotiq/addon/` (from `godot-addon/addons/godotiq`)
    - METADATA with version 0.1.0
  - Flag any unexpected or missing files
  - Completion criteria: All expected modules and addon files present in wheel

- [ ] **Task 6: Run full test suite**
  - Run: `.venv/bin/pytest tests/ -v --tb=short`
  - All tests must pass
  - Report total count and any warnings
  - Completion criteria: Zero test failures

- [ ] **Quality check: Final gate**
  - Build succeeded
  - Wheel contents verified
  - All tests pass

#### Phase Completion Criteria
- [ ] Clean build produces wheel and sdist without errors
- [ ] Wheel contains all expected modules, addon files, and metadata
- [ ] All tests pass with zero failures

#### Operational Verification Procedures
1. `ls -la dist/` -- verify two files exist (`.whl` and `.tar.gz`)
2. `unzip -l dist/godotiq-0.1.0-py3-none-any.whl | grep "godotiq/"` -- verify module listing
3. `unzip -l dist/godotiq-0.1.0-py3-none-any.whl | grep "addon/"` -- verify addon files included
4. `.venv/bin/pytest tests/ -v --tb=short` -- all green, zero failures
5. `pip install dist/godotiq-0.1.0-py3-none-any.whl && python -c "from godotiq import __version__; print(__version__)"` -- smoke test install (use a temp venv)

## Completion Criteria

- [ ] All phases completed
- [ ] Each phase's operational verification procedures executed
- [ ] No `print()` debug statements in license.py
- [ ] Cross-platform cache path implemented
- [ ] Production configuration verified (org ID, API URL, version)
- [ ] Clean wheel build with all expected contents
- [ ] Full test suite passes
- [ ] Ready for `twine upload dist/*`

## Progress Tracking

### Phase 1: Code Cleanup
- Start:
- Complete:
- Notes:

### Phase 2: Configuration Verification
- Start:
- Complete:
- Notes:

### Phase 3: Build and Test
- Start:
- Complete:
- Notes:

## Notes
- This checklist blocks the first PyPI upload of GodotIQ v0.1.0.
- After all checks pass, the upload command is: `twine upload dist/*` (or `python -m twine upload dist/*`).
- The `httpx` dependency is already declared in pyproject.toml (`httpx>=0.27`).
- Test file `tests/test_license.py` monkeypatches `_CACHE_DIR` and `_CACHE_FILE`, so the cache path refactor in Task 2 will not break existing tests.
- If any task fails, fix before proceeding -- do not skip checks.
