- Update prompt in .grokkit/prompts/rexx.md to emphasize Object Rexx features, extensions, and educational focus. - Revise analysis.md with improved tech stack descriptions, function references, data flow, and learning path for better clarity and precision.
48 lines
7.2 KiB
Markdown
48 lines
7.2 KiB
Markdown
# Project Analysis: rexx-address-book
|
|
|
|
## Tech Stack & Layout
|
|
- Object Rexx serves as the core language, blending procedural scripting with OOP for modular, extensible code; key extensions include Unix for system interactions (e.g., file handling, environment vars), SQLite for lightweight persistent storage, and ncurses for building a terminal-based UI (TUI); configuration uses JSON for flexibility, chosen to leverage Rexx's strengths in scripting while adding modern data and UI capabilities without heavy dependencies.
|
|
- High-level directory structure includes `app/` for core application modules and classes (e.g., database and UI logic), `db/` for database-related scripts or schemas (though integrated into `app/` in this setup), `tests/` for unit tests (e.g., database functionality), `addrbook.rex` as the main entry point script, `install.rex` for setup and configuration, and `default-config.json` for default settings like DB paths and UI themes, ensuring easy customization and portability.
|
|
|
|
## Module & Function Relationships
|
|
- The main script `addrbook.rex` acts as the orchestrator, loading classes from `app/` and invoking `install.rex` for initial setup; `install.rex` handles environment checks, DB initialization, and config loading to prepare the app for runtime.
|
|
- The SQLite backend (via `app/appdb.cls`) manages data persistence for contacts, while the ncurses frontend (via `app/appui.cls`) handles user interactions like menus and forms, separating concerns for maintainability.
|
|
- Configuration in `default-config.json` ties pieces together by defining paths (e.g., DB file), UI settings (e.g., colors), and defaults, which are parsed in `install.rex` and propagated to classes in `app/` for a unified, configurable experience.
|
|
|
|
## Function & Method Reference
|
|
### addrbook.rex (Main Entry Point)
|
|
- **main()**: Orchestrates app startup by loading configs, initializing DB and UI objects, and entering the main event loop; uses `::requires` to import classes, creates instances like `AppDB` and `AppUI`, and calls UI methods for user interaction; exists to centralize control flow, promoting a clean separation between setup and runtime.
|
|
- **handleExit()**: Cleans up resources like closing DB connections and ncurses sessions on exit; employs Object Rexx's `guard off` for safe object destruction and Unix extensions for any file cleanup; designed for graceful shutdown, ensuring data integrity and resource management.
|
|
|
|
### install.rex (Setup Script)
|
|
- **install()**: Checks system dependencies, parses `default-config.json` using Rexx stems for JSON data, sets up SQLite DB schema if needed; leverages Unix extensions for path validation and file creation; exists to make the app portable and user-friendly, handling one-time setup without cluttering the main script.
|
|
- **configLoad()**: Reads and validates JSON config into a Rexx directory object; uses classic Rexx parsing with stems to convert JSON to accessible structures; rationale is to enable dynamic configuration, allowing easy tweaks without code changes.
|
|
|
|
### app/appdb.cls (Database Class)
|
|
- **init()**: Initializes SQLite connection using extension calls like `sqlite_open`; sets up stems for contact records (e.g., `contacts.name`, `contacts.email`); uses Object Rexx classes for encapsulation, ensuring DB ops are object-oriented; exists to abstract storage, separating data logic from UI.
|
|
- **addContact()**: Inserts a new contact via SQLite execute with parameterized queries to prevent injection; maps input stems to SQL, handles transactions; designed for safety and efficiency, demonstrating Rexx's stem usage for flexible data handling.
|
|
- **queryContacts()**: Retrieves contacts with SQL select, populates Rexx arrays or stems; integrates SQLite results into objects; rationale is query optimization and easy data flow to UI, using OOP methods for reusability.
|
|
|
|
### app/appui.cls (UI Class)
|
|
- **init()**: Starts ncurses session with `initscr()` and sets up windows/menus; uses Object Rexx methods to manage UI state objects; exists to encapsulate TUI logic, leveraging ncurses for interactive terminal apps without GUI overhead.
|
|
- **displayMenu()**: Renders main menu using ncurses panels and handles key inputs via `getch()`; employs loops with conditionals for navigation, updating UI objects dynamically; designed for usability, separating input handling from business logic.
|
|
- **editContactForm()**: Creates form fields for contact editing, validates input, and calls DB methods; uses ncurses forms extension and Rexx stems for form data; rationale is intuitive user experience, with error handling built into methods.
|
|
|
|
### app/utils.rex (Utility Functions)
|
|
- **parseJson()**: Converts JSON strings to Rexx directories using procedural parsing; classic Rexx string functions like `pos()` and `substr()`; exists as a helper to avoid external libs, supporting config-driven design.
|
|
- **logError()**: Logs errors to file or console using Unix extensions; simple procedural function with condition signals; designed for debugging and robustness, keeping utils lightweight.
|
|
|
|
### tests/test_appdb.rexx (Test Suite)
|
|
- **testAddContact()**: Mocks DB insert and asserts results using Rexx's `assert` equivalents; calls class methods and checks stems; exists for TDD, ensuring DB reliability through isolated testing.
|
|
- **testQuery()**: Simulates queries and validates output structures; uses Object Rexx's testing patterns; rationale is to catch issues early, demonstrating separation of tests from production code.
|
|
|
|
## Object & Data Flow
|
|
- Main data structures include contact records as Rexx stems (e.g., `contact.1.name = "John"`) for flexible storage, and configuration as directory objects (e.g., `config~dbPath`) for easy access.
|
|
- Data flows from user input via ncurses UI methods (e.g., form submissions) to business logic in `addrbook.rex` (validation), then to SQLite backend for storage/retrieval (e.g., `appdb~addContact(stem)`); reverse flow pulls DB data into stems, formats via utils, and displays in UI windows.
|
|
- Error handling uses Object Rexx's `signal on` for conditions like `syntax` or `novalue`, with try-catch patterns in methods; safety includes parameterized SQLite queries and ncurses refresh checks to prevent crashes or data corruption.
|
|
|
|
## Learning Path & Gotchas
|
|
- Start with `addrbook.rex` for overall flow, then `install.rex` for setup, followed by `app/appdb.cls` and `app/appui.cls` to grasp OOP integration, utils for helpers, and tests for validation; this order builds from high-level to details.
|
|
- Common pitfalls for Object Rexx newcomers include confusing classic Rexx procedural code with OOP (e.g., overusing globals instead of methods), improper `::requires` for class loading, and mixing stems (dynamic arrays) with true objects—treat stems as lightweight data holders.
|
|
- Gotchas with ncurses include handling terminal resizes or key mappings across platforms (use `resizeterm()`), SQLite in Rexx requires careful extension loading and error codes, and Unix differences (e.g., paths on Windows vs. Linux) may need conditionals.
|
|
- Design decisions like UI-DB separation enhance modularity, JSON config allows extensibility without recompiles, and minimal dependencies showcase Object Rexx's power for self-contained CLI/TUI apps, making it ideal for hobbyists building real tools. |