# Implementation Hints and Learnings ## SmartProxy Usage ### Direct Component Usage - Use SmartProxy components directly instead of creating your own wrappers - SmartProxy already includes Port80Handler and NetworkProxy functionality - When using SmartProxy, configure it directly rather than instantiating Port80Handler or NetworkProxy separately ```typescript // PREFERRED: Use SmartProxy with built-in ACME support const smartProxy = new plugins.smartproxy.SmartProxy({ fromPort: 443, toPort: targetPort, targetIP: targetServer, sniEnabled: true, acme: { port: 80, enabled: true, autoRenew: true, useProduction: true, renewThresholdDays: 30, accountEmail: contactEmail }, globalPortRanges: [{ from: 443, to: 443 }], domainConfigs: [/* domain configurations */] }); ``` ### Certificate Management - SmartProxy has built-in ACME certificate management - Configure it in the `acme` property of SmartProxy options - Use `accountEmail` (not `email`) for the ACME contact email - SmartProxy handles both HTTP-01 challenges and certificate application automatically ## qenv Usage ### Direct Usage - Use qenv directly instead of creating environment variable wrappers - Instantiate qenv with appropriate basePath and nogitPath: ```typescript const qenv = new plugins.qenv.Qenv('./', '.nogit/'); const value = await qenv.getEnvVarOnDemand('ENV_VAR_NAME'); ``` ## TypeScript Interfaces ### SmartProxy Interfaces - Always check the interfaces from the node_modules to ensure correct property names - Important interfaces: - `ISmartProxyOptions`: Main configuration for SmartProxy - `IAcmeOptions`: ACME certificate configuration - `IDomainConfig`: Domain-specific configuration ### Required Properties - Remember to include all required properties in your interface implementations - For `ISmartProxyOptions`, `globalPortRanges` is required - For `IAcmeOptions`, use `accountEmail` for the contact email ## Testing ### Test Structure - Follow the project's test structure, using `@push.rocks/tapbundle` - Use `expect(value).toEqual(expected)` for equality checks - Use `expect(value).toBeTruthy()` for boolean assertions ```typescript tap.test('test description', async () => { const result = someFunction(); expect(result.property).toEqual('expected value'); expect(result.valid).toBeTruthy(); }); ``` ### Cleanup - Include a cleanup test to ensure proper test resource handling - Add a `stop` test to forcefully end the test when needed: ```typescript tap.test('stop', async () => { await tap.stopForcefully(); }); ``` ## Architecture Principles ### Simplicity - Prefer direct usage of libraries instead of creating wrappers - Don't reinvent functionality that already exists in dependencies - Keep interfaces clean and focused, avoiding unnecessary abstraction layers ### Component Integration - Leverage built-in integrations between components (like SmartProxy's ACME handling) - Use parallel operations for performance (like in the `stop()` method) - Separate concerns clearly (HTTP handling vs. SMTP handling)