ARCHIVED 2026-05-01 — Preserved for historical context. See current docs for current state.
Feature Name: Powernode System
Menu Category: System
Source: /home/rett/Drive/Projects/powernode-server (Rails 4.2.4)
Target: /home/rett/Drive/Projects/powernode-platform (Rails 8)
Status: Planning Phase
Last Updated: 2025-12-15
- Executive Summary
- Source Application Analysis
- Model Conflict Analysis
- Migration Strategy
- Phase Breakdown
- Implementation Checklist
- Open Questions
- Progress Tracking
- Frontend Navigation Structure
- Feature Name: Powernode System
- Menu Location: System category in navigation
- Model Prefix:
System::namespace for all new infrastructure models - Permission Prefix:
system.*for infrastructure permissions
| Decision | Choice | Rationale |
|---|---|---|
| Scope | Node infrastructure ONLY | Skip account/plan/user/invitation - already exists |
| Model Namespace | System:: |
Clean separation, no conflicts |
| Agents | Extend Worker model | Reuse existing authentication infrastructure |
| Operations | System::Operation |
Separate from AuditLog (different purpose) |
| Providers | Pluggable architecture | Extensible for any cloud provider |
| Puppet | Skip (later enhancement) | Focus on core infrastructure first |
| Pages | Skip entirely | Not needed for this implementation |
| File Storage | Use FileObject/FileStorage | Existing infrastructure handles versioning |
| Data Migration | Start fresh | No legacy data to migrate |
| Plan Limits | Add to limits JSON | node_limit, instance_limit in Plan.limits |
| User Fields | Skip | authorized_keys/preferences not needed |
The powernode-server is a node infrastructure provisioning and lifecycle management platform built on Rails 4.2.4. It provides:
- Node Management: Physical and cloud-based node provisioning
- Cloud Provider Integration: AWS and OpenStack support
- Configuration Management: Puppet module integration
- Template System: Node templates with platform/architecture hierarchy
- Multi-tenant Architecture: Account-scoped resources with delegation
| Metric | Source (powernode-server) | Target (powernode-platform) |
|---|---|---|
| Rails Version | 4.2.4 | 8.x |
| Total Models | 41 | 180+ |
| Controllers | 31 | TBD |
| Primary Key Type | UUID v1 | UUID v7 |
| Authentication | Devise | Custom JWT |
| Authorization | CanCan (role-based) | Permission-based |
| File Uploads | Paperclip | ActiveStorage |
| Encryption | attr_encrypted | ActiveRecord Encryption |
- High Complexity: Authentication/Authorization refactoring
- Medium Complexity: Model associations, file upload migration
- Low Complexity: New models without conflicts
| Model | Associations | Migration Status |
|---|---|---|
User |
belongs_to: account; has_many: account_delegations, accounts (through), invitation | |
Account |
belongs_to: agent, owner (User), plan; has_many: users, nodes, providers, etc. | |
Plan |
belongs_to: account; has_many: accounts, pages | |
Invitation |
belongs_to: account, user | |
AccountDelegation |
belongs_to: account, user | |
CreditCard |
Stripe integration |
| Model | Associations | Purpose |
|---|---|---|
Node |
belongs_to: account, agent, node_template; has_many: node_instances, operations | Core node entity |
NodeInstance |
belongs_to: node, provider_*, has_many: node_modules, operations | Cloud/physical instance |
NodeModule |
belongs_to: account, node_platform; has_many: dependencies, subscriptions | Configuration module |
NodeTemplate |
belongs_to: account, node_platform; has_many: nodes, module_subscriptions | Node blueprint |
NodePlatform |
belongs_to: account, node_architecture, *_script; has_many: node_modules, templates | OS/platform definition |
NodeArchitecture |
belongs_to: account; has_many: node_platforms | System architecture |
NodeScript |
belongs_to: account | Build/init/sync scripts |
NodeModuleCategory |
belongs_to: account; has_many: node_modules | Module categorization |
NodeModuleCopyPath |
belongs_to: account | Module deployment paths |
NodeModuleSubscription |
belongs_to: node, node_module | Node-module join |
NodeModuleDependency |
belongs_to: node_module, dependency | Module dependencies |
NodeMountPoint |
belongs_to: account, node_module | Filesystem mounts |
NodeMountPointSubscription |
belongs_to: node_instance, node_mount_point | Instance-mount join |
NodeTemplateModuleSubscription |
belongs_to: node_template, node_module | Template-module join |
NodeModulePuppetModuleSubscription |
belongs_to: node_module, puppet_module | Module-puppet join |
| Model | Associations | Purpose |
|---|---|---|
Provider |
belongs_to: account; has_many: provider_regions | Cloud provider (AWS/OpenStack) |
ProviderRegion |
belongs_to: account, provider; has_many: zones, networks | Geographic region |
ProviderAvailabilityZone |
belongs_to: account, provider_region | Availability zone |
ProviderConnection |
belongs_to: account; encrypted: secret_key | Provider credentials |
ProviderInstanceType |
belongs_to: account; has_many: region_subscriptions | Compute instance types |
ProviderNetwork |
belongs_to: account, provider_region; has_many: subnets | Virtual network |
ProviderNetworkSubnet |
belongs_to: provider_network, availability_zone | Network subnet |
ProviderVolume |
belongs_to: account, region, volume_type; has_many: members | Storage volume |
ProviderVolumeType |
belongs_to: account, mount_script | Storage type |
ProviderVolumeMember |
belongs_to: provider_volume, account | Volume attachment |
ProviderVolumeSnapshot |
belongs_to: provider_volume | Volume snapshot |
ProviderRegionInstanceTypeSubscription |
Join table | Region-instance type |
ProviderRegionVolumeTypeSubscription |
Join table | Region-volume type |
| Model | Associations | Purpose |
|---|---|---|
PuppetModule |
belongs_to: account; has_many: puppet_resources | Puppet module |
PuppetResource |
belongs_to: puppet_module | Puppet resource |
| Model | Associations | Migration Status |
|---|---|---|
Operation |
belongs_to: account, operable (polymorphic) | |
Agent |
belongs_to: account; has_many: accounts | |
Page |
belongs_to: account, pageable (polymorphic) | |
PageResource |
belongs_to: page | |
Ability |
CanCan authorization |
| Aspect | Source | Target | Migration Path |
|---|---|---|---|
| Primary Key | UUID v1 (uuid_generate_v1()) |
UUID v7 | Generate new UUIDv7 on import |
| Foreign Keys | UUID references | UUID references | Maintain referential integrity |
| Indexes | Standard Rails | Optimized for UUIDv7 | Recreate during migration |
| Source Field | Encryption Method | Target Equivalent |
|---|---|---|
| Node.ssh_key | attr_encrypted (IV + salt) | ActiveRecord Encryption |
| Node.ssh_host_key | attr_encrypted | ActiveRecord Encryption |
| NodeInstance.key | attr_encrypted | ActiveRecord Encryption |
| ProviderConnection.secret_key | attr_encrypted | ActiveRecord Encryption |
| Agent.encrypted_key | SCrypt::Password | ActiveRecord Encryption |
| Model | Column | Content | Notes |
|---|---|---|---|
| User | roles | Array of role strings | Convert to UserRole joins |
| User | authorized_keys | SSH keys | Move to dedicated model? |
| User | preferences | User settings | Merge with target User |
| Plan | default_roles | Role assignments | Convert to permissions |
| Plan | options | Feature flags | Map to Plan.features |
| Account | (various) | Settings | Merge with Account.settings |
| NodeModule | mask, file_spec, package_spec, dependency_spec | Specs | Keep as JSON |
| ProviderRegion | capabilities | Region features | Keep as JSON |
# User roles (JSON array)
["global_admin", "account_admin", "node_manager", "provider_publisher"]
# Ability.rb patterns
can :manage, :all if user.has_role?(:global_admin)
can :manage, Node if user.has_any_role?(:node_admin, :node_manager)
can :read, Node if user.has_role?(:node_publisher)# Permission format: resource.action
["nodes.create", "nodes.read", "nodes.update", "nodes.delete", "nodes.manage"]
# Controller pattern
before_action -> { authorize_permission!('nodes.manage') }| Source Role | Target Permissions |
|---|---|
global_admin |
system.admin (grants all) |
account_admin |
accounts.manage, users.manage, billing.manage |
account_manager |
accounts.read, billing.read, users.read |
node_admin |
nodes.manage, node_instances.manage, node_modules.manage |
node_manager |
nodes.create, nodes.read, nodes.update, node_instances.* |
node_publisher |
nodes.read, node_modules.read |
provider_admin |
providers.manage, provider_regions.manage, provider_connections.manage |
provider_manager |
providers.* (except delete) |
provider_publisher |
providers.read, provider_regions.read |
puppet_admin |
puppet_modules.manage, puppet_resources.manage |
puppet_manager |
puppet_modules.* |
puppet_publisher |
puppet_modules.read |
| Controller | Actions | Priority | Notes |
|---|---|---|---|
api/agent_v1/agent_api_controller |
RESTful + file ops | HIGH | Agent communication API |
api/node_v1/node_api_controller |
Node self-service | HIGH | Node bootstrapping |
nodes_controller |
CRUD + control | HIGH | Core node management |
node_instances_controller |
Edit/Show/Update | HIGH | Instance management |
node_modules_controller |
CRUD + deps + download | HIGH | Module management |
node_templates_controller |
CRUD + import/export | MEDIUM | Template management |
node_platforms_controller |
CRUD | MEDIUM | Platform management |
node_architectures_controller |
CRUD + download | MEDIUM | Architecture management |
node_scripts_controller |
CRUD | MEDIUM | Script management |
node_module_categories_controller |
CRUD | LOW | Category management |
node_module_copy_paths_controller |
CRUD | LOW | Copy path management |
node_mount_points_controller |
CRUD | LOW | Mount point management |
providers_controller |
CRUD | HIGH | Provider management |
provider_regions_controller |
CRUD | HIGH | Region management |
provider_connections_controller |
CRUD | HIGH | Connection management |
provider_availability_zones_controller |
CRUD | MEDIUM | Zone management |
provider_instance_types_controller |
CRUD | MEDIUM | Instance types |
provider_networks_controller |
CRUD | MEDIUM | Network management |
provider_network_subnets_controller |
CRUD | MEDIUM | Subnet management |
provider_volumes_controller |
CRUD | MEDIUM | Volume management |
provider_volume_types_controller |
CRUD | LOW | Volume types |
operations_controller |
CRUD + control | HIGH | Operation tracking |
puppet_modules_controller |
CRUD | MEDIUM | Puppet modules |
agents_controller |
CRUD | HIGH | Agent management |
accounts_controller |
Billing + delegation | SKIP | Use existing |
users_controller |
CRUD | SKIP | Use existing |
invitations_controller |
CRUD | SKIP | Use existing |
plans_controller |
CRUD | SKIP | Use existing |
pages_controller |
CRUD + resources | EVALUATE | May extend existing |
registrations_controller |
Devise custom | SKIP | Use existing auth |
| Conflicting Model | Source Purpose | Target Purpose | Resolution Options |
|---|---|---|---|
| User | Devise auth, roles (JSON), authorized_keys | JWT auth, permission-based, 2FA | A) Extend target User with source fields B) Keep separate (rename source) |
| Account | Multi-tenant container, Stripe integration, agent association | Multi-tenant container, settings, termination workflow | A) Extend target Account B) Merge carefully |
| Plan | Billing plan with limits (node/user/instance), Stripe sync | Billing plan with features/limits JSON, trial support | A) Extend target Plan with node limits B) Keep separate |
| Invitation | User invitation with recipient email | User invitation with token, sent_at, accepted_at | A) Extend target Invitation B) Merge |
| AccountDelegation | User delegation with expiration | User delegation with expiration | A) Use existing (nearly identical) |
| Page | Polymorphic content pages with resources | CMS pages with author, published_at | A) Extend with polymorphic support B) Rename source to ResourcePage |
| PageResource | Media attachments to pages | Does not exist | A) Add to target B) Use FileObject instead |
| Source Model | Similar Target Model | Difference | Resolution |
|---|---|---|---|
| Agent | AiAgent | Infrastructure agent vs AI agent | Rename source to InfraAgent |
| Operation | AuditLog | Task tracking vs change tracking | Keep both - different purposes |
| CreditCard | PaymentMethod | Single card vs multiple methods | Use PaymentMethod |
| Ability | Permission | CanCan vs custom | Convert to permissions |
| Source Association | Target Association | Conflict Level |
|---|---|---|
belongs_to :account |
belongs_to :account |
✅ Compatible |
has_many :account_delegations |
has_many :account_delegations |
✅ Compatible |
has_one :invitation |
(none) | |
roles (JSON) |
has_many :roles through: :user_roles |
❌ Convert |
authorized_keys (JSON) |
(none) | |
preferences (JSON) |
(none) |
| Source Association | Target Association | Conflict Level |
|---|---|---|
belongs_to :owner (User) |
(none) | |
belongs_to :agent |
(none - different Agent) | |
belongs_to :plan |
has_one :subscription -> plan |
|
has_many :nodes, providers, etc. |
(none) | ✅ Add new |
| State machine (trialing/active/delinquent) | (none - uses Subscription) |
| Source Association | Target Association | Conflict Level |
|---|---|---|
belongs_to :account |
(none) | |
user_limit, node_limit, instance_limit |
limits (JSON) |
|
default_roles (JSON) |
(none) | |
| Stripe fields | Stripe fields | ✅ Compatible |
Strategy: Incremental Extension
- Extend existing models where overlap exists (User, Account, Plan, Invitation)
- Create new models for unique functionality (Node*, Provider*, Puppet*)
- Rename conflicting models where semantics differ (Agent → InfraAgent)
- Convert authorization from roles to permissions
- Migrate file uploads from Paperclip to ActiveStorage
- Modernize encryption from attr_encrypted to ActiveRecord Encryption
| Source Model | Target Model Name | Rationale |
|---|---|---|
| User | User (extended) | Core model, extend with new fields |
| Account | Account (extended) | Core model, extend with new associations |
| Plan | Plan (extended) | Core model, add node/instance limits |
| Invitation | Invitation (extended) | Nearly identical, minor extension |
| AccountDelegation | AccountDelegation | Use existing |
| Agent | InfraAgent | Avoid conflict with AiAgent |
| Page | NodePage or extend Page | TBD - depends on polymorphic needs |
| PageResource | NodePageResource or FileObject | TBD |
| Operation | InfraOperation | Different from AuditLog |
| CreditCard | (skip - use PaymentMethod) | Redundant |
| Ability | (skip - convert to Permission) | Different pattern |
| Node | Node (new) | No conflict |
| NodeInstance | NodeInstance (new) | No conflict |
| (all other Node* models) | (same names) | No conflicts |
| Provider | Provider (new) | No conflict |
| (all other Provider* models) | (same names) | No conflicts |
| PuppetModule | PuppetModule (new) | No conflict |
| PuppetResource | PuppetResource (new) | No conflict |
# Node Management
nodes.create, nodes.read, nodes.update, nodes.delete, nodes.manage
node_instances.create, node_instances.read, node_instances.update, node_instances.delete, node_instances.manage
node_modules.create, node_modules.read, node_modules.update, node_modules.delete, node_modules.manage
node_templates.create, node_templates.read, node_templates.update, node_templates.delete, node_templates.manage
node_platforms.create, node_platforms.read, node_platforms.update, node_platforms.delete, node_platforms.manage
node_architectures.create, node_architectures.read, node_architectures.update, node_architectures.delete, node_architectures.manage
node_scripts.create, node_scripts.read, node_scripts.update, node_scripts.delete, node_scripts.manage
# Provider Management
providers.create, providers.read, providers.update, providers.delete, providers.manage
provider_regions.create, provider_regions.read, provider_regions.update, provider_regions.delete, provider_regions.manage
provider_connections.create, provider_connections.read, provider_connections.update, provider_connections.delete, provider_connections.manage
provider_networks.create, provider_networks.read, provider_networks.update, provider_networks.delete, provider_networks.manage
provider_volumes.create, provider_volumes.read, provider_volumes.update, provider_volumes.delete, provider_volumes.manage
# Puppet Management
puppet_modules.create, puppet_modules.read, puppet_modules.update, puppet_modules.delete, puppet_modules.manage
puppet_resources.create, puppet_resources.read, puppet_resources.update, puppet_resources.delete, puppet_resources.manage
# Infrastructure Operations
infra_operations.create, infra_operations.read, infra_operations.update, infra_operations.delete, infra_operations.manage
infra_agents.create, infra_agents.read, infra_agents.update, infra_agents.delete, infra_agents.manage
Goal: Prepare target platform for migration
- Add infrastructure fields to User model
- Add infrastructure associations to Account model
- Add node/instance limits to Plan model
- Extend Invitation model if needed
- Create
InfraAgentmodel (renamed from Agent) - Add InfraAgent-Account associations
- Implement authentication mechanism
- Define all new permissions in seeds
- Create role templates for infrastructure management
- Test permission enforcement
Goal: Implement core node management
- Create Node model with encrypted fields
- Create NodeInstance model with encrypted key
- Create NodeTemplate model
- Create NodePlatform model
- Create NodeArchitecture model
- Create NodeScript model
- Create NodeModule model with versioning
- Create NodeModuleCategory model
- Create NodeModuleCopyPath model
- Create NodeModuleSubscription join model
- Create NodeModuleDependency model
- Create NodeMountPoint model
- Create NodeMountPointSubscription join model
- Create NodeTemplateModuleSubscription join model
- Create Api::V1::NodesController
- Create Api::V1::NodeInstancesController
- Create Api::V1::NodeModulesController
- Create Api::V1::NodeTemplatesController
- Create remaining node controllers
- Create agent API namespace
Goal: Implement cloud provider integration
- Create Provider model
- Create ProviderRegion model
- Create ProviderAvailabilityZone model
- Create ProviderConnection model (encrypted)
- Create ProviderInstanceType model
- Create ProviderNetwork model
- Create ProviderNetworkSubnet model
- Create ProviderVolume model
- Create ProviderVolumeType model
- Create ProviderVolumeMember model
- Create ProviderVolumeSnapshot model
- Create region subscription join tables
- Create Api::V1::ProvidersController
- Create Api::V1::ProviderRegionsController
- Create remaining provider controllers
Goal: Implement Puppet integration and operations tracking
- Create PuppetModule model
- Create PuppetResource model
- Create NodeModulePuppetModuleSubscription join model
- Create InfraOperation model (polymorphic)
- Implement status state machine
- Add scheduling support
- Create Api::V1::PuppetModulesController
- Create Api::V1::InfraOperationsController
Goal: Migrate Paperclip attachments to ActiveStorage
- Configure ActiveStorage for infrastructure files
- Create storage service configurations
- Migrate NodeArchitecture attachments (kernel, ramdisk, image)
- Migrate NodeInstance attachments (image)
- Migrate NodeModule attachments (data)
- Migrate PuppetModule attachments (data)
- Migrate PageResource attachments (data)
Goal: Create React frontend components
- Create node list/detail pages
- Create node instance management
- Create node module management
- Create node template management
- Create provider configuration pages
- Create region/zone management
- Create network configuration UI
- Create volume management UI
- Create operations dashboard
- Create operation detail/control views
Goal: Migrate existing data and comprehensive testing
- Create migration rake tasks
- Handle UUID conversion (v1 → v7)
- Migrate encrypted fields
- Migrate file attachments
- Validate data integrity
- Unit tests for all new models
- Integration tests for controllers
- API contract tests
- Permission enforcement tests
- End-to-end tests
- InfraAgent (renamed from Agent)
- InfraOperation (renamed from Operation)
- Node
- NodeInstance
- NodeModule
- NodeModuleCategory
- NodeModuleCopyPath
- NodeModuleSubscription
- NodeModuleDependency
- NodeModulePuppetModuleSubscription
- NodeMountPoint
- NodeMountPointSubscription
- NodePlatform
- NodeArchitecture
- NodeScript
- NodeTemplate
- NodeTemplateModuleSubscription
- Provider
- ProviderRegion
- ProviderAvailabilityZone
- ProviderConnection
- ProviderInstanceType
- ProviderNetwork
- ProviderNetworkSubnet
- ProviderVolume
- ProviderVolumeType
- ProviderVolumeMember
- ProviderVolumeSnapshot
- ProviderRegionInstanceTypeSubscription
- ProviderRegionVolumeTypeSubscription
- PuppetModule
- PuppetResource
- NodePage (if needed - TBD)
- NodePageResource (if needed - TBD)
- User - add authorized_keys, preferences
- Account - add owner_id, infra_agent association
- Plan - add node_limit, instance_limit to limits JSON
- Api::V1::NodesController
- Api::V1::NodeInstancesController
- Api::V1::NodeModulesController
- Api::V1::NodeModuleCategoriesController
- Api::V1::NodeModuleCopyPathsController
- Api::V1::NodeMountPointsController
- Api::V1::NodePlatformsController
- Api::V1::NodeArchitecturesController
- Api::V1::NodeScriptsController
- Api::V1::NodeTemplatesController
- Api::V1::ProvidersController
- Api::V1::ProviderRegionsController
- Api::V1::ProviderAvailabilityZonesController
- Api::V1::ProviderConnectionsController
- Api::V1::ProviderInstanceTypesController
- Api::V1::ProviderNetworksController
- Api::V1::ProviderNetworkSubnetsController
- Api::V1::ProviderVolumesController
- Api::V1::ProviderVolumeTypesController
- Api::V1::PuppetModulesController
- Api::V1::InfraAgentsController
- Api::V1::InfraOperationsController
- Api::AgentV1::* (Agent API namespace)
- Api::NodeV1::* (Node API namespace)
- Node permissions (7)
- NodeInstance permissions (7)
- NodeModule permissions (7)
- NodeTemplate permissions (7)
- NodePlatform permissions (7)
- NodeArchitecture permissions (7)
- NodeScript permissions (7)
- Provider permissions (7)
- ProviderRegion permissions (7)
- ProviderConnection permissions (7)
- ProviderNetwork permissions (7)
- ProviderVolume permissions (7)
- PuppetModule permissions (7)
- InfraAgent permissions (7)
- InfraOperation permissions (7)
- Add infrastructure fields to users
- Add infrastructure fields to accounts
- Add infrastructure limits to plans
- Create infra_agents table
- Create infra_operations table
- Create nodes table
- Create node_instances table
- Create node_modules table
- Create node_module_categories table
- Create node_module_copy_paths table
- Create node_module_subscriptions table
- Create node_module_dependencies table
- Create node_mount_points table
- Create node_mount_point_subscriptions table
- Create node_platforms table
- Create node_architectures table
- Create node_scripts table
- Create node_templates table
- Create node_template_module_subscriptions table
- Create node_module_puppet_module_subscriptions table
- Create providers table
- Create provider_regions table
- Create provider_availability_zones table
- Create provider_connections table
- Create provider_instance_types table
- Create provider_networks table
- Create provider_network_subnets table
- Create provider_volumes table
- Create provider_volume_types table
- Create provider_volume_members table
- Create provider_volume_snapshots table
- Create provider_region_instance_type_subscriptions table
- Create provider_region_volume_type_subscriptions table
- Create puppet_modules table
- Create puppet_resources table
- Seed new permissions
Question: How should we handle the authorized_keys field from the source User model?
Options:
- A) Add as JSON column to target User model
- B) Create separate
UserAuthorizedKeymodel with has_many association - C) Skip - not needed for this deployment
Current Answer: PENDING
Question: The source Account belongs_to :owner (User). Should we add this to the target?
Options:
- A) Yes - add
owner_idforeign key to Account - B) No - use first user with
accounts.managepermission - C) Create
AccountOwnershipjoin table for flexibility
Current Answer: PENDING
Question: Source Plan has user_limit, node_limit, instance_limit as separate columns. Target Plan has limits JSON. How to reconcile?
Options:
- A) Add to existing
limitsJSON:{ ..., "node_limit": 10, "instance_limit": 50 } - B) Add as separate columns for query performance
- C) Create PlanLimit model for normalization
Current Answer: PENDING
Question: Source Page is polymorphic (pageable_type, pageable_id). Target Page is CMS-focused. How to handle?
Options:
- A) Extend target Page with polymorphic support
- B) Create new
ResourcePagemodel for infrastructure pages - C) Skip - use different documentation approach
Current Answer: PENDING
Question: Source has Agent for infrastructure agents. Target has AiAgent for AI agents. What to name the infrastructure agent?
Options:
- A)
InfraAgent(infrastructure agent) - B)
NodeAgent(node-specific agent) - C)
ProvisioningAgent(provisioning-focused) - D)
Agentwithagent_typecolumn to differentiate
Current Answer: PENDING
Question: Source Operation tracks infrastructure tasks with status/progress. Target AuditLog tracks data changes. Relationship?
Options:
- A) Create separate
InfraOperationmodel (different purpose) - B) Extend AuditLog with operation features
- C) Create
Jobmodel that links to AuditLog entries
Current Answer: PENDING
Question: Source supports AWS and OpenStack. Should we add more providers? Options:
- A) Keep AWS and OpenStack only
- B) Add GCP, Azure, DigitalOcean support
- C) Make provider types pluggable/extensible
Current Answer: PENDING
Question: Source uses attr_encrypted with per-attribute IV. Target uses ActiveRecord::Encryption. Migration approach?
Options:
- A) Re-encrypt all data during migration (breaking change)
- B) Support both encryption methods temporarily
- C) Store source data as-is, encrypt only new records
Current Answer: PENDING
Question: Source uses Paperclip with local filesystem + S3. Target uses ActiveStorage. Migration approach? Options:
- A) Migrate all files to ActiveStorage during migration
- B) Keep legacy files in place, use ActiveStorage for new
- C) Use hybrid approach with migration over time
Current Answer: PENDING
Question: Source has api/agent_v1 and api/node_v1 namespaces. How to integrate?
Options:
- A) Create under existing
Api::V1namespace - B) Create separate
Api::AgentV1andApi::NodeV1namespaces - C) Create
Api::V1::Agent::*andApi::V1::Node::*nested namespaces
Current Answer: PENDING
Question: Source Account has AASM state machine (trialing → active ↔ delinquent). Target uses Subscription states. Reconcile?
Question: Should new controllers use the existing authorization pattern or create an infrastructure-specific concern?
Question: Source User has Devise fields (confirmable, lockable, etc.). Target has custom JWT. Migrate Devise fields or skip?
Question: Source NodeModule uses acts_as_versioned. Implement in target or use alternative?
| Phase | Status | Progress | Notes |
|---|---|---|---|
| Planning | 🟡 In Progress | 60% | Awaiting conflict resolution answers |
| Phase 1: Foundation | ⬜ Not Started | 0% | |
| Phase 2: Node Infrastructure | ⬜ Not Started | 0% | |
| Phase 3: Provider Infrastructure | ⬜ Not Started | 0% | |
| Phase 4: Puppet & Operations | ⬜ Not Started | 0% | |
| Phase 5: File Migration | ⬜ Not Started | 0% | |
| Phase 6: Frontend Integration | ⬜ Not Started | 0% | |
| Phase 7: Data Migration & Testing | ⬜ Not Started | 0% |
| Date | Question | Decision | Rationale |
|---|---|---|---|
| 2025-12-15 | Initial analysis | Complete | Comprehensive source/target analysis |
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Data loss during encryption migration | Medium | High | Test thoroughly, maintain backups |
| Permission mapping gaps | Low | Medium | Comprehensive mapping document |
| File attachment corruption | Low | High | Validate checksums during migration |
| API compatibility breaks | Medium | Medium | Version APIs, maintain backwards compat |
The Powernode System features will be organized under the "System" navigation category.
System (Category)
├── Nodes
│ ├── All Nodes (list)
│ ├── Node Details (detail)
│ ├── Node Instances (sub-section)
│ └── Node Templates (sub-section)
├── Modules
│ ├── All Modules (list)
│ ├── Module Categories
│ └── Mount Points
├── Platforms
│ ├── All Platforms (list)
│ └── Architectures
├── Scripts (list)
├── Providers
│ ├── All Providers (list)
│ ├── Regions
│ ├── Connections
│ └── Networks
├── Storage
│ ├── Volumes
│ ├── Volume Types
│ └── Snapshots
├── Puppet
│ ├── Modules
│ └── Resources
├── Agents (list)
└── Operations (list/dashboard)
Each menu item will require appropriate system.* permissions:
system.nodes.read- View nodes menusystem.providers.read- View providers menusystem.puppet.read- View puppet menusystem.operations.read- View operations menusystem.agents.read- View agents menu
To maintain organization, models will use the System:: namespace:
System::NodeSystem::NodeInstanceSystem::ProviderSystem::Agent(instead of InfraAgent)System::Operation
This keeps all Powernode System models organized and prevents conflicts with existing models.
See source analysis for complete schema details.
See target inventory for complete schema details.
To be added during implementation
Document Version: 1.0 Created: 2025-12-15 Author: Claude Code Migration Assistant