conversant 1.0.18 → 1.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -1
  3. data/.gitlab-ci.yml +12 -1
  4. data/.rubocop.yml +43 -6
  5. data/CHANGELOG.md +20 -0
  6. data/Gemfile +1 -1
  7. data/README.md +8 -15
  8. data/Rakefile +1 -1
  9. data/conversant.gemspec +7 -2
  10. data/examples/inheritance_integration.rb +1 -4
  11. data/lib/conversant/configuration.rb +17 -19
  12. data/lib/conversant/v3/base.rb +1 -1
  13. data/lib/conversant/v3/http_client.rb +29 -31
  14. data/lib/conversant/v3/mixins/authentication.rb +1 -1
  15. data/lib/conversant/v3/services/cdn/analytics.rb +11 -19
  16. data/lib/conversant/v3/services/cdn/audit.rb +1 -1
  17. data/lib/conversant/v3/services/cdn/certificate.rb +1 -1
  18. data/lib/conversant/v3/services/cdn/dashboard.rb +1 -1
  19. data/lib/conversant/v3/services/cdn/domain.rb +6 -7
  20. data/lib/conversant/v3/services/cdn/monitoring.rb +1 -1
  21. data/lib/conversant/v3/services/cdn/partner/analytics.rb +1 -1
  22. data/lib/conversant/v3/services/cdn/partner.rb +1 -1
  23. data/lib/conversant/v3/services/lms/dashboard.rb +3 -5
  24. data/lib/conversant/v3/services/lms/domain.rb +1 -1
  25. data/lib/conversant/v3/services/lms/job.rb +42 -52
  26. data/lib/conversant/v3/services/lms/partner/analytics.rb +1 -1
  27. data/lib/conversant/v3/services/lms/partner.rb +1 -1
  28. data/lib/conversant/v3/services/lms/preset.rb +1 -1
  29. data/lib/conversant/v3/services/lms.rb +0 -2
  30. data/lib/conversant/v3/services/oss/partner/analytics.rb +1 -1
  31. data/lib/conversant/v3/services/oss/partner.rb +1 -1
  32. data/lib/conversant/v3/services/oss.rb +1 -1
  33. data/lib/conversant/v3/services/portal/dashboard.rb +1 -1
  34. data/lib/conversant/v3/services/portal.rb +1 -1
  35. data/lib/conversant/v3/services/vms/analytics.rb +1 -1
  36. data/lib/conversant/v3/services/vms/business.rb +1 -1
  37. data/lib/conversant/v3/services/vms/partner/analytics.rb +1 -1
  38. data/lib/conversant/v3/services/vms/transcoding.rb +3 -3
  39. data/lib/conversant/v3.rb +1 -1
  40. data/lib/conversant/version.rb +1 -1
  41. data/plans/templates/bug-fix-template.md +69 -0
  42. data/plans/templates/feature-implementation-template.md +84 -0
  43. data/plans/templates/refactor-template.md +82 -0
  44. data/plans/templates/template-usage-guide.md +58 -0
  45. data/sig/conversant/v3/services/lms.rbs +3 -4
  46. data/sig/conversant/v3.rbs +1 -1
  47. metadata +11 -6
@@ -4,9 +4,9 @@ module Conversant
4
4
  module V3
5
5
  module Services
6
6
  class LMS
7
- # Job management service for live streaming operations
7
+ # Job management service for live-streaming operations
8
8
  #
9
- # Provides comprehensive job management functionality for live streaming including:
9
+ # Provides comprehensive job management functionality for live-streaming including:
10
10
  # - Job listing and filtering
11
11
  # - Job status tracking
12
12
  # - Stream profile information
@@ -61,9 +61,15 @@ module Conversant
61
61
  # - :encoder [String] encoder IP address
62
62
  # - :server [String] execution server
63
63
  # - :manifest [String] manifest URL
64
- # - :profiles [Array<Hash>] array of stream profiles
64
+ # - :profiles_count [Integer] number of stream profiles
65
65
  # - :transcoding [Boolean] transcoding enabled
66
66
  # - :gpu [Boolean] GPU acceleration enabled
67
+ # - :ha [Boolean] high availability enabled
68
+ # - :dvr [Boolean] DVR enabled
69
+ # - :dai [Boolean] dynamic ad insertion enabled
70
+ # - :encrypted [Boolean] stream encryption enabled
71
+ # - :ingest_url [String] RTMP ingest URL
72
+ # - :play_domain [String] playback domain
67
73
  #
68
74
  # @example Get streaming jobs
69
75
  # jobs = lms.job.where(status: 'streaming', limit: 50)
@@ -75,23 +81,19 @@ module Conversant
75
81
  # all_jobs = lms.job.where
76
82
  #
77
83
  # @since 1.0.0
84
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
78
85
  def where(**params)
79
86
  response = JSON.parse(@parent.send(:call, 'GET', "/v4/streams?#{params.to_query}"))
80
87
  return nil unless response
81
88
 
82
- items = response['list'] || response[:list] || []
89
+ items = [response['list'] || response[:list] || []].flatten.map(&:with_indifferent_access)
83
90
 
84
91
  items.map do |item|
85
- status = item['status']&.to_i || item[:status]&.to_i
86
- inbound = item['stream_rtmp_inbound'] || item[:stream_rtmp_inbound]
87
-
88
- profiles = (item['stream_rtmp_outbounds'] || item[:stream_rtmp_outbounds])&.map do |stream|
89
- {
90
- preset: stream['preset_name'] || stream[:preset_name],
91
- type: stream['type'] || stream[:type],
92
- profile: build_profile_url(inbound, item, stream)
93
- }
94
- end
92
+ status = item[:status]&.to_i
93
+ inbound = item[:stream_rtmp_inbound]
94
+ play_domain = item[:play_domain] || item['play_domain']
95
+ outbounds = item[:stream_rtmp_outbounds] || item['stream_rtmp_outbounds'] || []
96
+ output_type = outbounds.first && (outbounds.first['type'] || outbounds.first[:type])
95
97
 
96
98
  {
97
99
  entity: item['osp_id'] || item[:osp_id],
@@ -103,31 +105,44 @@ module Conversant
103
105
  started_at: parse_timestamp(item['started'] || item[:started]),
104
106
  ended_at: parse_timestamp(item['ended'] || item[:ended]),
105
107
  client: inbound && (inbound['client_ip'] || inbound[:client_ip]),
108
+ ingest_url: inbound&.dig(:push_url) || inbound&.dig('push_url'),
106
109
  encoder: extract_encoder(item),
107
110
  server: item['exec_ta'] || item[:exec_ta],
108
- manifest: build_manifest_url(inbound, item, profiles),
109
- profiles: profiles || [],
111
+ manifest: build_manifest_url(play_domain, item, output_type),
112
+ profiles_count: outbounds.size,
110
113
  transcoding: item['transcoding'] || item[:transcoding],
111
- gpu: (item['gpu'] || item[:gpu]) == 'gpu'
114
+ gpu: (item['gpu'] || item[:gpu]) == 'gpu',
115
+ ha: item['ha'] || item[:ha],
116
+ dvr: item['dvr'] || item[:dvr],
117
+ dai: item['dai'] || item[:dai],
118
+ encrypted: item[:stream_encrypts]&.any? || item['stream_encrypts']&.any?,
119
+ play_domain: play_domain
112
120
  }
113
121
  end
114
122
  rescue StandardError => e
115
123
  @parent.send(:logger).error "LMS::Job.where error: #{e.message}"
116
124
  nil
117
125
  end
126
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
118
127
 
119
128
  private
120
129
 
121
130
  # Parse numeric status code to string
122
131
  #
123
132
  # @param status [Integer] numeric status code
124
- # @return [String, Integer] status string or original code if unknown
133
+ # @return [String] status string or 'unknown_N' if unknown
125
134
  def parse_status(status)
126
135
  case status
127
136
  when 1 then 'ready'
128
137
  when 2 then 'streaming'
138
+ when 3 then 'stopped'
139
+ when 4 then 'error'
140
+ when 5 then 'starting'
141
+ when 6 then 'stopping'
142
+ when 7 then 'restarting'
143
+ when 8 then 'pending'
129
144
  when 12 then 'interrupted'
130
- else status
145
+ else "unknown_#{status}"
131
146
  end
132
147
  end
133
148
 
@@ -164,48 +179,23 @@ module Conversant
164
179
  end
165
180
  end
166
181
 
167
- # Build profile URL for a stream
168
- #
169
- # @param inbound [Hash] inbound stream configuration
170
- # @param item [Hash] job item hash
171
- # @param stream [Hash] stream profile configuration
172
- # @return [String, nil] profile URL or nil if inbound is missing
173
- def build_profile_url(inbound, item, stream)
174
- return nil unless inbound
175
-
176
- domain = inbound['domain'] || inbound[:domain]
177
- app = item['app'] || item[:app]
178
- stream_name = item['stream'] || item[:stream]
179
- preset = stream['preset_name'] || stream[:preset_name]
180
- type = stream['type'] || stream[:type]
181
-
182
- "http://#{domain}/#{app}/#{stream_name}-#{preset}#{stream_extension(type)}"
183
- end
184
-
185
182
  # Build manifest URL for a job
186
183
  #
187
- # @param inbound [Hash] inbound stream configuration
184
+ # @param play_domain [String] playback domain
188
185
  # @param item [Hash] job item hash
189
- # @param profiles [Array<Hash>] array of stream profiles
190
- # @return [String, nil] manifest URL or nil if inbound is missing
191
- def build_manifest_url(inbound, item, profiles)
192
- return nil unless inbound
186
+ # @param output_type [String] output stream type ('hls', 'dash')
187
+ # @return [String, nil] manifest URL or nil if play_domain is missing
188
+ def build_manifest_url(play_domain, item, output_type)
189
+ return nil unless play_domain
193
190
 
194
- domain = inbound['domain'] || inbound[:domain]
195
191
  app = item['app'] || item[:app]
196
192
  manifest_name = item['manifest_name'] || item[:manifest_name]
193
+ ext = stream_extension(output_type)
197
194
 
198
- ext = if profiles&.first
199
- type = profiles.first[:type]
200
- stream_extension(type)
201
- else
202
- ''
203
- end
204
-
205
- "http://#{domain}/#{app}/#{manifest_name}#{ext}"
195
+ "https://#{play_domain}/#{app}/#{manifest_name}#{ext}"
206
196
  end
207
197
  end
208
198
  end
209
199
  end
210
200
  end
211
- end
201
+ end
@@ -263,4 +263,4 @@ module Conversant
263
263
  end
264
264
  end
265
265
  end
266
- end
266
+ end
@@ -55,4 +55,4 @@ end
55
55
  # Load nested analytics class after Partner is defined
56
56
  require_relative 'partner/analytics'
57
57
  require_relative 'partner/report'
58
- require_relative 'partner/business'
58
+ require_relative 'partner/business'
@@ -54,4 +54,4 @@ module Conversant
54
54
  end
55
55
  end
56
56
  end
57
- end
57
+ end
@@ -104,8 +104,6 @@ module Conversant
104
104
  response.body
105
105
  end
106
106
 
107
- protected
108
-
109
107
  def service_endpoint
110
108
  configuration.private_lms_endpoint
111
109
  end
@@ -102,4 +102,4 @@ module Conversant
102
102
  end
103
103
  end
104
104
  end
105
- end
105
+ end
@@ -45,4 +45,4 @@ module Conversant
45
45
  end
46
46
 
47
47
  # Load nested analytics class after Partner is defined
48
- require_relative 'partner/analytics'
48
+ require_relative 'partner/analytics'
@@ -125,4 +125,4 @@ module Conversant
125
125
  end
126
126
 
127
127
  # Load nested service classes after OSS is defined
128
- require_relative 'oss/partner'
128
+ require_relative 'oss/partner'
@@ -111,4 +111,4 @@ module Conversant
111
111
  end
112
112
  end
113
113
  end
114
- end
114
+ end
@@ -84,7 +84,7 @@ module Conversant
84
84
  deleted: item['deleted'],
85
85
  pop: item['pop'],
86
86
  volume: item['volume'],
87
- federation: item['federationVolume'],
87
+ federation: item['federationVolume']
88
88
  }
89
89
  end.to_json
90
90
 
@@ -111,4 +111,4 @@ module Conversant
111
111
  end
112
112
  end
113
113
  end
114
- end
114
+ end
@@ -187,4 +187,4 @@ module Conversant
187
187
  end
188
188
  end
189
189
  end
190
- end
190
+ end
@@ -130,4 +130,4 @@ module Conversant
130
130
  end
131
131
  end
132
132
  end
133
- end
133
+ end
@@ -108,7 +108,7 @@ module Conversant
108
108
  response = @parent.send(:call, 'GET', "/v2/jobs?#{merged_payload.to_query}")
109
109
  return [] if response.nil?
110
110
 
111
- JSON.parse(response)&.[]("list") || []
111
+ JSON.parse(response)&.[]('list') || []
112
112
  rescue StandardError => e
113
113
  logger.error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
114
114
  []
@@ -163,7 +163,7 @@ module Conversant
163
163
  response = @parent.send(:call, 'GET', "/v2/osp/presets?#{merged_payload.to_query}")
164
164
  return [] if response.nil?
165
165
 
166
- JSON.parse(response)&.[]("list") || []
166
+ JSON.parse(response)&.[]('list') || []
167
167
  rescue StandardError => e
168
168
  logger.error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
169
169
  []
@@ -181,4 +181,4 @@ module Conversant
181
181
  end
182
182
  end
183
183
  end
184
- end
184
+ end
data/lib/conversant/v3.rb CHANGED
@@ -33,4 +33,4 @@ module Conversant
33
33
  end
34
34
  end
35
35
  end
36
- end
36
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Conversant
4
- VERSION = '1.0.18'
4
+ VERSION = '1.0.20'
5
5
  end
@@ -0,0 +1,69 @@
1
+ # [Bug Fix] Implementation Plan
2
+
3
+ **Date**: YYYY-MM-DD
4
+ **Type**: Bug Fix
5
+ **Priority**: [Critical/High/Medium/Low]
6
+ **Context Tokens**: <150 words
7
+
8
+ ## Executive Summary
9
+ Brief description of the bug and its impact.
10
+
11
+ ## Issue Analysis
12
+ ### Symptoms
13
+ - [ ] Symptom 1
14
+ - [ ] Symptom 2
15
+
16
+ ### Root Cause
17
+ Brief explanation of the underlying cause.
18
+
19
+ ### Evidence
20
+ - **Logs**: Reference to log files (don't include full logs)
21
+ - **Error Messages**: Key error patterns
22
+ - **Affected Components**: List of impacted files/modules
23
+
24
+ ## Context Links
25
+ - **Related Issues**: [GitHub issue numbers]
26
+ - **Recent Changes**: [Relevant commits or PRs]
27
+ - **Dependencies**: [Related systems]
28
+
29
+ ## Solution Design
30
+ ### Approach
31
+ High-level fix strategy in 2-3 sentences.
32
+
33
+ ### Changes Required
34
+ 1. **File 1** (`path/to/file.ts`): Brief change description
35
+ 2. **File 2** (`path/to/file.ts`): Brief change description
36
+
37
+ ### Testing Changes
38
+ - [ ] Update existing tests
39
+ - [ ] Add new test cases
40
+ - [ ] Validate fix doesn't break existing functionality
41
+
42
+ ## Implementation Steps
43
+ 1. [ ] Step 1 - file: `path/to/file.ts`
44
+ 2. [ ] Step 2 - file: `path/to/file.ts`
45
+ 3. [ ] Run test suite
46
+ 4. [ ] Validate fix in relevant environments
47
+
48
+ ## Verification Plan
49
+ ### Test Cases
50
+ - [ ] Test case 1: Expected behavior
51
+ - [ ] Test case 2: Edge case handling
52
+ - [ ] Regression test: Ensure no new issues
53
+
54
+ ### Rollback Plan
55
+ If the fix causes issues:
56
+ 1. Revert commit: `git revert <commit-hash>`
57
+ 2. Restore previous behavior in files X, Y, Z
58
+
59
+ ## Risk Assessment
60
+ | Risk | Impact | Mitigation |
61
+ |------|--------|------------|
62
+ | Risk 1 | Medium | Mitigation plan |
63
+
64
+ ## TODO Checklist
65
+ - [ ] Implement fix
66
+ - [ ] Update tests
67
+ - [ ] Run full test suite
68
+ - [ ] Code review
69
+ - [ ] Deploy and verify
@@ -0,0 +1,84 @@
1
+ # [Feature Name] Implementation Plan
2
+
3
+ **Date**: YYYY-MM-DD
4
+ **Type**: Feature Implementation
5
+ **Status**: Planning
6
+ **Context Tokens**: <200 words
7
+
8
+ ## Executive Summary
9
+ Brief 2-3 sentence description of the feature and its business value.
10
+
11
+ ## Context Links
12
+ - **Related Plans**: [List other plan files - no full content]
13
+ - **Dependencies**: [External systems, APIs, existing features]
14
+ - **Reference Docs**: [Link to docs in ./docs directory]
15
+
16
+ ## Requirements
17
+ ### Functional Requirements
18
+ - [ ] Requirement 1
19
+ - [ ] Requirement 2
20
+
21
+ ### Non-Functional Requirements
22
+ - [ ] Performance target
23
+ - [ ] Security requirement
24
+ - [ ] Scalability requirement
25
+
26
+ ## Architecture Overview
27
+ ```mermaid
28
+ [Simple component diagram]
29
+ ```
30
+
31
+ ### Key Components
32
+ - **Component 1**: Brief description
33
+ - **Component 2**: Brief description
34
+
35
+ ### Data Models
36
+ - **Model 1**: Key fields
37
+ - **Model 2**: Key fields
38
+
39
+ ## Implementation Phases
40
+
41
+ ### Phase 1: [Name] (Est: X days)
42
+ **Scope**: Specific boundaries
43
+ **Tasks**:
44
+ 1. [ ] Task 1 - file: `path/to/file.ts`
45
+ 2. [ ] Task 2 - file: `path/to/file.ts`
46
+
47
+ **Acceptance Criteria**:
48
+ - [ ] Criteria 1
49
+ - [ ] Criteria 2
50
+
51
+ ### Phase 2: [Name] (Est: X days)
52
+ [Repeat structure]
53
+
54
+ ## Testing Strategy
55
+ - **Unit Tests**: Specific test coverage targets
56
+ - **Integration Tests**: Key interaction points
57
+ - **E2E Tests**: Critical user flows
58
+
59
+ ## Security Considerations
60
+ - [ ] Security item 1
61
+ - [ ] Security item 2
62
+
63
+ ## Risk Assessment
64
+ | Risk | Impact | Mitigation |
65
+ |------|--------|------------|
66
+ | Risk 1 | High | Mitigation strategy |
67
+
68
+ ## Quick Reference
69
+ ### Key Commands
70
+ ```bash
71
+ npm run command
72
+ ```
73
+
74
+ ### Configuration Files
75
+ - `config/file.ts`: Purpose
76
+ - `.env.example`: Environment variables
77
+
78
+ ## TODO Checklist
79
+ - [ ] Phase 1 Task 1
80
+ - [ ] Phase 1 Task 2
81
+ - [ ] Phase 2 Task 1
82
+ - [ ] Testing complete
83
+ - [ ] Documentation updated
84
+ - [ ] Code review passed
@@ -0,0 +1,82 @@
1
+ # [Component/Module] Refactoring Plan
2
+
3
+ **Date**: YYYY-MM-DD
4
+ **Type**: Refactoring
5
+ **Scope**: [Module/Component/System level]
6
+ **Context Tokens**: <200 words
7
+
8
+ ## Executive Summary
9
+ Brief description of what is being refactored and why.
10
+
11
+ ## Current State Analysis
12
+ ### Issues with Current Implementation
13
+ - [ ] Issue 1: Performance bottleneck
14
+ - [ ] Issue 2: Code maintainability
15
+ - [ ] Issue 3: Technical debt
16
+
17
+ ### Metrics (Before)
18
+ - **Performance**: Current benchmarks
19
+ - **Code Quality**: Complexity metrics
20
+ - **Test Coverage**: Current percentage
21
+
22
+ ## Context Links
23
+ - **Affected Modules**: [List without full content]
24
+ - **Dependencies**: [Other systems impacted]
25
+ - **Related Documentation**: [Links to docs]
26
+
27
+ ## Refactoring Strategy
28
+ ### Approach
29
+ High-level strategy for the refactoring in 2-3 sentences.
30
+
31
+ ### Architecture Changes
32
+ ```mermaid
33
+ [Before/After comparison diagram]
34
+ ```
35
+
36
+ ### Key Improvements
37
+ - **Improvement 1**: Brief description
38
+ - **Improvement 2**: Brief description
39
+
40
+ ## Implementation Plan
41
+
42
+ ### Phase 1: Preparation (Est: X days)
43
+ **Scope**: Setup and preparation work
44
+ 1. [ ] Create comprehensive tests for current functionality
45
+ 2. [ ] Document current behavior
46
+ 3. [ ] Identify all dependencies
47
+
48
+ ### Phase 2: Core Refactoring (Est: X days)
49
+ **Scope**: Main refactoring work
50
+ 1. [ ] Refactor component A - file: `path/to/file.ts`
51
+ 2. [ ] Refactor component B - file: `path/to/file.ts`
52
+ 3. [ ] Update integration points
53
+
54
+ ### Phase 3: Integration & Testing (Est: X days)
55
+ **Scope**: Validation and cleanup
56
+ 1. [ ] Integration testing
57
+ 2. [ ] Performance validation
58
+ 3. [ ] Documentation updates
59
+
60
+ ## Backward Compatibility
61
+ - **Breaking Changes**: [List any breaking changes]
62
+ - **Migration Path**: [Steps for users/systems]
63
+ - **Deprecation Timeline**: [If applicable]
64
+
65
+ ## Success Metrics (After)
66
+ - **Performance**: Target improvements
67
+ - **Code Quality**: Target metrics
68
+ - **Test Coverage**: Target percentage
69
+
70
+ ## Risk Assessment
71
+ | Risk | Impact | Mitigation |
72
+ |------|--------|------------|
73
+ | Breaking changes | High | Comprehensive testing |
74
+ | Performance regression | Medium | Benchmarking |
75
+
76
+ ## TODO Checklist
77
+ - [ ] Phase 1: Preparation complete
78
+ - [ ] Phase 2: Core refactoring complete
79
+ - [ ] Phase 3: Integration complete
80
+ - [ ] Performance benchmarks validated
81
+ - [ ] Documentation updated
82
+ - [ ] Code review passed
@@ -0,0 +1,58 @@
1
+ # Plan Template Usage Guide
2
+
3
+ ## Template Selection
4
+
5
+ ### Feature Implementation Template
6
+ **Use when**: Adding new functionality, endpoints, services, or modules
7
+ **File**: `feature-implementation-template.md`
8
+ **Size**: Medium to large scope changes
9
+
10
+ ### Bug Fix Template
11
+ **Use when**: Fixing specific issues, errors, or broken functionality
12
+ **File**: `bug-fix-template.md`
13
+ **Size**: Small to medium scope changes
14
+
15
+ ### Refactoring Template
16
+ **Use when**: Improving code structure, performance, or maintainability without changing functionality
17
+ **File**: `refactor-template.md`
18
+ **Size**: Medium to large scope changes
19
+
20
+ ## Context Management Best Practices
21
+
22
+ ### Keep Plans Focused
23
+ - **Executive Summary**: Max 3 sentences
24
+ - **Context Links**: Reference files, don't include full content
25
+ - **Tasks**: Max 10 per phase
26
+ - **Context Tokens**: Target <200 words for summaries
27
+
28
+ ### Template Adaptation
29
+ 1. Copy the appropriate template to `plans/YYMMDD-feature-name-plan.md`
30
+ 2. Replace bracketed placeholders with actual content
31
+ 3. Remove sections not relevant to your specific use case
32
+ 4. Keep the core structure intact for consistency
33
+
34
+ ### Cross-References Instead of Duplication
35
+ - Link to existing documentation in `./docs/`
36
+ - Reference other plans without copying content
37
+ - Use file paths instead of code blocks where possible
38
+ - Focus on "what" and "why", not detailed "how"
39
+
40
+ ## Quality Checklist
41
+
42
+ Before finalizing any plan:
43
+ - [ ] Executive summary is clear and concise
44
+ - [ ] Tasks are specific and actionable
45
+ - [ ] File paths are included for implementation tasks
46
+ - [ ] Success criteria are measurable
47
+ - [ ] Context links are used instead of full content
48
+ - [ ] TODO checklist is complete and realistic
49
+
50
+ ## Context Refresh Triggers
51
+
52
+ Use these templates when:
53
+ - Starting a new development phase
54
+ - Switching between different types of work (feature → bugfix)
55
+ - After major context accumulation (>8000 tokens)
56
+ - When agent handoffs occur
57
+
58
+ This ensures each plan starts with fresh, focused context optimized for the specific task type.
@@ -9,16 +9,15 @@ module Conversant
9
9
  attr_reader parent: LMS
10
10
 
11
11
  def initialize: (LMS parent) -> void
12
- def where: (**untyped params) -> Array[Hash[String, untyped]]
12
+ def where: (**untyped params) -> Array[Hash[Symbol, untyped]]?
13
13
 
14
14
  private
15
15
 
16
- def parse_status: (Integer | String | nil status) -> String
16
+ def parse_status: (Integer status) -> String
17
17
  def parse_timestamp: (Integer | String | nil timestamp) -> DateTime?
18
18
  def extract_encoder: (Hash[String | Symbol, untyped] item) -> String
19
19
  def stream_extension: (String? type) -> String
20
- def build_profile_url: (Hash[String | Symbol, untyped]? inbound, Hash[String | Symbol, untyped] item, Hash[String | Symbol, untyped]? stream) -> String?
21
- def build_manifest_url: (Hash[String | Symbol, untyped]? inbound, Hash[String | Symbol, untyped] item, Array[Hash[Symbol, untyped]]? profiles) -> String?
20
+ def build_manifest_url: (String? play_domain, Hash[String | Symbol, untyped] item, String? output_type) -> String?
22
21
  end
23
22
 
24
23
  # Domain management for LMS
@@ -29,7 +29,6 @@ module Conversant
29
29
 
30
30
  # HTTP client module
31
31
  module HttpClient
32
- LOGIN_URL: String
33
32
  PORTAL_SESSION_REDIS_KEY: String
34
33
  SSO_GW_SESSION2_REDIS_KEY: String
35
34
 
@@ -48,6 +47,7 @@ module Conversant
48
47
  def update_cookie_jar: (untyped response) -> void
49
48
  def parse_cookie_to_jar: (String cookie_string) -> void
50
49
  def extract_form_action: (String html_body) -> String?
50
+ def login_url: () -> String
51
51
  def configuration: () -> Conversant::Configuration
52
52
  def redis: () -> untyped
53
53
  end