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.
@@ -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.