mintsoft 0.1.0
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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.serena/memories/code_style_conventions.md +35 -0
- data/.serena/memories/codebase_structure.md +35 -0
- data/.serena/memories/development_environment.md +37 -0
- data/.serena/memories/project_overview.md +28 -0
- data/.serena/memories/suggested_commands.md +63 -0
- data/.serena/memories/task_completion_checklist.md +46 -0
- data/.serena/project.yml +68 -0
- data/.standard.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +165 -0
- data/Rakefile +10 -0
- data/claudedocs/AUTH_CLIENT_DESIGN.md +294 -0
- data/claudedocs/FINAL_SIMPLIFIED_DESIGN.md +553 -0
- data/claudedocs/IMPLEMENTATION_SUMMARY.md +140 -0
- data/claudedocs/INDEX.md +83 -0
- data/claudedocs/MINIMAL_IMPLEMENTATION_PLAN.md +316 -0
- data/claudedocs/TOKEN_ONLY_CLIENT_DESIGN.md +408 -0
- data/claudedocs/USAGE_EXAMPLES.md +482 -0
- data/examples/complete_workflow.rb +146 -0
- data/lib/mintsoft/auth_client.rb +104 -0
- data/lib/mintsoft/base.rb +44 -0
- data/lib/mintsoft/client.rb +37 -0
- data/lib/mintsoft/errors.rb +9 -0
- data/lib/mintsoft/objects/order.rb +16 -0
- data/lib/mintsoft/objects/return.rb +26 -0
- data/lib/mintsoft/objects/return_reason.rb +11 -0
- data/lib/mintsoft/resources/base_resource.rb +53 -0
- data/lib/mintsoft/resources/orders.rb +36 -0
- data/lib/mintsoft/resources/returns.rb +90 -0
- data/lib/mintsoft/version.rb +5 -0
- data/lib/mintsoft.rb +17 -0
- data/sig/mintsoft.rbs +4 -0
- metadata +161 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# AuthClient Design
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The gem provides a separate `AuthClient` that handles token authentication through an `auth` resource. This keeps authentication separate from the main API client while providing a clean interface for token management.
|
|
6
|
+
|
|
7
|
+
## Architecture
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Mintsoft Gem Structure
|
|
11
|
+
├── AuthClient (separate from main client)
|
|
12
|
+
│ └── Auth Resource (POST /api/auth)
|
|
13
|
+
├── Client (main API client - token only)
|
|
14
|
+
│ ├── Orders Resource
|
|
15
|
+
│ └── Returns Resource
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## AuthClient Implementation
|
|
19
|
+
|
|
20
|
+
### 1. AuthClient Class (Faraday-based)
|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
# lib/mintsoft/auth_client.rb
|
|
24
|
+
require "faraday"
|
|
25
|
+
require "faraday/net_http"
|
|
26
|
+
|
|
27
|
+
module Mintsoft
|
|
28
|
+
class AuthClient
|
|
29
|
+
BASE_URL = "https://api.mintsoft.com".freeze
|
|
30
|
+
|
|
31
|
+
def initialize(base_url: BASE_URL, conn_opts: {})
|
|
32
|
+
@base_url = base_url
|
|
33
|
+
@conn_opts = conn_opts
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def connection
|
|
37
|
+
@connection ||= Faraday.new do |conn|
|
|
38
|
+
conn.url_prefix = @base_url
|
|
39
|
+
conn.options.merge!(@conn_opts)
|
|
40
|
+
conn.request :json
|
|
41
|
+
conn.response :json, content_type: "application/json"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def auth
|
|
46
|
+
@auth ||= Resources::Auth.new(self)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 2. Auth Resource (Faraday-based)
|
|
53
|
+
|
|
54
|
+
```ruby
|
|
55
|
+
# lib/mintsoft/resources/auth.rb
|
|
56
|
+
module Mintsoft
|
|
57
|
+
module Resources
|
|
58
|
+
class Auth
|
|
59
|
+
def initialize(client)
|
|
60
|
+
@client = client
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def authenticate(username, password)
|
|
64
|
+
validate_credentials!(username, password)
|
|
65
|
+
|
|
66
|
+
payload = {
|
|
67
|
+
username: username,
|
|
68
|
+
password: password
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
response = @client.connection.post('/api/auth', payload)
|
|
72
|
+
|
|
73
|
+
if response.success?
|
|
74
|
+
response.body # Returns token string directly
|
|
75
|
+
else
|
|
76
|
+
handle_auth_error(response)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
def validate_credentials!(username, password)
|
|
83
|
+
raise ValidationError, "Username is required" if username.nil? || username.empty?
|
|
84
|
+
raise ValidationError, "Password is required" if password.nil? || password.empty?
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def handle_auth_error(response)
|
|
88
|
+
case response.status
|
|
89
|
+
when 400
|
|
90
|
+
raise ValidationError, "Invalid request: #{extract_error_message(response)}"
|
|
91
|
+
when 401
|
|
92
|
+
raise AuthenticationError, "Invalid credentials"
|
|
93
|
+
when 500
|
|
94
|
+
raise APIError, "Internal server error"
|
|
95
|
+
else
|
|
96
|
+
raise APIError, "Authentication failed: #{response.status}"
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def extract_error_message(response)
|
|
101
|
+
return response.body['message'] if response.body.is_a?(Hash)
|
|
102
|
+
'Bad request'
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 3. BaseResource for Common Patterns
|
|
110
|
+
|
|
111
|
+
```ruby
|
|
112
|
+
# lib/mintsoft/resources/base_resource.rb
|
|
113
|
+
module Mintsoft
|
|
114
|
+
class BaseResource
|
|
115
|
+
attr_reader :client
|
|
116
|
+
|
|
117
|
+
def initialize(client)
|
|
118
|
+
@client = client
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
protected
|
|
122
|
+
|
|
123
|
+
def get_request(url, params: {}, headers: {})
|
|
124
|
+
handle_response client.connection.get(url, params, headers)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def post_request(url, body: {}, headers: {})
|
|
128
|
+
handle_response client.connection.post(url, body, headers)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
private
|
|
132
|
+
|
|
133
|
+
def handle_response(response)
|
|
134
|
+
case response.status
|
|
135
|
+
when 400
|
|
136
|
+
raise ValidationError, "Invalid request: #{response.body}"
|
|
137
|
+
when 401
|
|
138
|
+
raise AuthenticationError, "Invalid or expired token"
|
|
139
|
+
when 403
|
|
140
|
+
raise AuthenticationError, "Access denied"
|
|
141
|
+
when 404
|
|
142
|
+
raise NotFoundError, "Resource not found"
|
|
143
|
+
when 500
|
|
144
|
+
raise APIError, "Internal server error"
|
|
145
|
+
else
|
|
146
|
+
response
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Usage Examples
|
|
154
|
+
|
|
155
|
+
### 1. Basic Token Retrieval
|
|
156
|
+
|
|
157
|
+
```ruby
|
|
158
|
+
# Initialize auth client
|
|
159
|
+
auth_client = Mintsoft::AuthClient.new
|
|
160
|
+
|
|
161
|
+
# Get token directly as string
|
|
162
|
+
token = auth_client.auth.authenticate(
|
|
163
|
+
ENV['MINTSOFT_USERNAME'],
|
|
164
|
+
ENV['MINTSOFT_PASSWORD']
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
puts "Token: #{token}"
|
|
168
|
+
|
|
169
|
+
# Use token with main client
|
|
170
|
+
client = Mintsoft::Client.new(token: token)
|
|
171
|
+
orders = client.orders.search("ORD-2024-001")
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### 2. With Error Handling
|
|
175
|
+
|
|
176
|
+
```ruby
|
|
177
|
+
auth_client = Mintsoft::AuthClient.new
|
|
178
|
+
|
|
179
|
+
begin
|
|
180
|
+
token = auth_client.auth.authenticate(username, password)
|
|
181
|
+
|
|
182
|
+
puts "Authentication successful!"
|
|
183
|
+
puts "Token: #{token}"
|
|
184
|
+
|
|
185
|
+
client = Mintsoft::Client.new(token: token)
|
|
186
|
+
|
|
187
|
+
rescue Mintsoft::AuthenticationError => e
|
|
188
|
+
puts "Invalid credentials: #{e.message}"
|
|
189
|
+
rescue Mintsoft::ValidationError => e
|
|
190
|
+
puts "Validation error: #{e.message}"
|
|
191
|
+
rescue Mintsoft::APIError => e
|
|
192
|
+
puts "API error: #{e.message}"
|
|
193
|
+
end
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### 3. Custom Base URL
|
|
197
|
+
|
|
198
|
+
```ruby
|
|
199
|
+
# For different environments
|
|
200
|
+
auth_client = Mintsoft::AuthClient.new(
|
|
201
|
+
base_url: 'https://staging.mintsoft.com/api'
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
token = auth_client.auth.authenticate("user", "pass")
|
|
205
|
+
|
|
206
|
+
# Use with matching base URL for main client
|
|
207
|
+
client = Mintsoft::Client.new(
|
|
208
|
+
token: token,
|
|
209
|
+
base_url: 'https://staging.mintsoft.com/api'
|
|
210
|
+
)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Updated File Structure
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
lib/
|
|
217
|
+
├── mintsoft.rb # Main entry point
|
|
218
|
+
├── mintsoft/
|
|
219
|
+
│ ├── version.rb # Version constant
|
|
220
|
+
│ ├── client.rb # Main API client (Faraday-based, token-only)
|
|
221
|
+
│ ├── auth_client.rb # Authentication client (Faraday-based)
|
|
222
|
+
│ ├── base.rb # Base OpenStruct object
|
|
223
|
+
│ ├── errors.rb # Error classes
|
|
224
|
+
│ ├── resources/
|
|
225
|
+
│ │ ├── base_resource.rb # Base resource with common Faraday patterns
|
|
226
|
+
│ │ ├── auth.rb # Auth resource (POST /api/auth)
|
|
227
|
+
│ │ ├── orders.rb # Orders resource
|
|
228
|
+
│ │ └── returns.rb # Returns resource
|
|
229
|
+
│ └── objects/
|
|
230
|
+
│ ├── order.rb # Order object
|
|
231
|
+
│ ├── return.rb # Return object
|
|
232
|
+
│ └── return_reason.rb # Return reason object
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Benefits
|
|
236
|
+
|
|
237
|
+
### 1. **Clean Separation**
|
|
238
|
+
|
|
239
|
+
- AuthClient for token management
|
|
240
|
+
- Client for API operations
|
|
241
|
+
- Clear responsibility boundaries
|
|
242
|
+
|
|
243
|
+
### 2. **Consistent Interface**
|
|
244
|
+
|
|
245
|
+
- Same resource pattern as main client
|
|
246
|
+
- Familiar API design
|
|
247
|
+
- Easy to understand and use
|
|
248
|
+
|
|
249
|
+
### 3. **Flexible Usage**
|
|
250
|
+
|
|
251
|
+
- Can use AuthClient independently
|
|
252
|
+
- Easy integration with token management systems
|
|
253
|
+
- Supports custom base URLs for different environments
|
|
254
|
+
|
|
255
|
+
### 4. **Enhanced Error Handling**
|
|
256
|
+
|
|
257
|
+
- Specific error types for authentication
|
|
258
|
+
- Detailed error messages
|
|
259
|
+
- Validation of input parameters
|
|
260
|
+
|
|
261
|
+
### 5. **Rich Token Information**
|
|
262
|
+
|
|
263
|
+
- Expiration tracking
|
|
264
|
+
- Token validation helpers
|
|
265
|
+
- Structured response data
|
|
266
|
+
|
|
267
|
+
## Main Entry Point Update
|
|
268
|
+
|
|
269
|
+
```ruby
|
|
270
|
+
# lib/mintsoft.rb
|
|
271
|
+
require_relative 'mintsoft/version'
|
|
272
|
+
require_relative 'mintsoft/errors'
|
|
273
|
+
require_relative 'mintsoft/base'
|
|
274
|
+
require_relative 'mintsoft/client'
|
|
275
|
+
require_relative 'mintsoft/auth_client'
|
|
276
|
+
|
|
277
|
+
# Resources
|
|
278
|
+
require_relative 'mintsoft/resources/base_resource'
|
|
279
|
+
require_relative 'mintsoft/resources/auth'
|
|
280
|
+
require_relative 'mintsoft/resources/orders'
|
|
281
|
+
require_relative 'mintsoft/resources/returns'
|
|
282
|
+
|
|
283
|
+
# Objects
|
|
284
|
+
require_relative 'mintsoft/objects/order'
|
|
285
|
+
require_relative 'mintsoft/objects/return'
|
|
286
|
+
require_relative 'mintsoft/objects/return_reason'
|
|
287
|
+
|
|
288
|
+
module Mintsoft
|
|
289
|
+
class Error < StandardError; end
|
|
290
|
+
# ... other error classes
|
|
291
|
+
end
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
This design provides a clean, consistent interface for authentication while maintaining the separation between token management and API operations.
|