Compare commits
3 Commits
05ea67144f
...
15533285c6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15533285c6 | ||
|
|
fa996683c3 | ||
|
|
ad6ce08e3e |
@@ -1,314 +1,274 @@
|
|||||||
# Backend Development Patterns
|
# .NET Development Best Practices
|
||||||
|
|
||||||
Backend architecture patterns for Python/FastAPI/PostgreSQL applications.
|
## Project Structure
|
||||||
|
|
||||||
## API Design
|
|
||||||
|
|
||||||
### RESTful Structure
|
|
||||||
|
|
||||||
```
|
```
|
||||||
GET /api/v1/documents # List
|
src/
|
||||||
GET /api/v1/documents/{id} # Get
|
Domain/ # Entities, value objects, domain events
|
||||||
POST /api/v1/documents # Create
|
Application/ # Use cases, DTOs, interfaces
|
||||||
PUT /api/v1/documents/{id} # Replace
|
Infrastructure/ # EF Core, external services
|
||||||
PATCH /api/v1/documents/{id} # Update
|
Api/ # Controllers, middleware, filters
|
||||||
DELETE /api/v1/documents/{id} # Delete
|
tests/
|
||||||
|
Unit/
|
||||||
GET /api/v1/documents?status=processed&sort=created_at&limit=20&offset=0
|
Integration/
|
||||||
```
|
```
|
||||||
|
|
||||||
### FastAPI Route Pattern
|
## Code Style
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
from fastapi import APIRouter, HTTPException, Depends, Query, File, UploadFile
|
// Use records for DTOs and value objects
|
||||||
from pydantic import BaseModel
|
public sealed record CreateDocumentRequest(string Name, string Type);
|
||||||
|
|
||||||
router = APIRouter(prefix="/api/v1", tags=["inference"])
|
// Use primary constructors
|
||||||
|
public class DocumentService(IRepository<Document> repo, ILogger<DocumentService> logger)
|
||||||
|
{
|
||||||
|
public async Task<Document?> GetAsync(Guid id, CancellationToken ct) =>
|
||||||
|
await repo.GetByIdAsync(id, ct);
|
||||||
|
}
|
||||||
|
|
||||||
@router.post("/infer", response_model=ApiResponse[InferenceResult])
|
// Prefer expression body for simple methods
|
||||||
async def infer_document(
|
public Document? FindById(Guid id) => _documents.FirstOrDefault(d => d.Id == id);
|
||||||
file: UploadFile = File(...),
|
|
||||||
confidence_threshold: float = Query(0.5, ge=0, le=1),
|
// Use collection expressions
|
||||||
service: InferenceService = Depends(get_inference_service)
|
int[] numbers = [1, 2, 3];
|
||||||
) -> ApiResponse[InferenceResult]:
|
List<string> names = ["Alice", "Bob"];
|
||||||
result = await service.process(file, confidence_threshold)
|
|
||||||
return ApiResponse(success=True, data=result)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Consistent Response Schema
|
## Async/Await
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
from typing import Generic, TypeVar
|
// Always pass CancellationToken
|
||||||
T = TypeVar('T')
|
public async Task<Document> GetAsync(Guid id, CancellationToken ct)
|
||||||
|
|
||||||
class ApiResponse(BaseModel, Generic[T]):
|
// Use ConfigureAwait(false) in libraries
|
||||||
success: bool
|
await _httpClient.GetAsync(url, ct).ConfigureAwait(false);
|
||||||
data: T | None = None
|
|
||||||
error: str | None = None
|
// Avoid async void (except event handlers)
|
||||||
meta: dict | None = None
|
public async Task ProcessAsync() { } // Good
|
||||||
|
public async void Process() { } // Bad
|
||||||
|
|
||||||
|
// Use ValueTask for hot paths with frequent sync completion
|
||||||
|
public ValueTask<int> GetCachedCountAsync()
|
||||||
```
|
```
|
||||||
|
|
||||||
## Core Patterns
|
## Dependency Injection
|
||||||
|
|
||||||
### Repository Pattern
|
```csharp
|
||||||
|
// Register by interface
|
||||||
|
builder.Services.AddScoped<IDocumentService, DocumentService>();
|
||||||
|
|
||||||
```python
|
// Use Options pattern for configuration
|
||||||
from typing import Protocol
|
builder.Services.Configure<AppSettings>(builder.Configuration.GetSection("App"));
|
||||||
|
|
||||||
class DocumentRepository(Protocol):
|
public class MyService(IOptions<AppSettings> options)
|
||||||
def find_all(self, filters: dict | None = None) -> list[Document]: ...
|
{
|
||||||
def find_by_id(self, id: str) -> Document | None: ...
|
private readonly AppSettings _settings = options.Value;
|
||||||
def create(self, data: dict) -> Document: ...
|
}
|
||||||
def update(self, id: str, data: dict) -> Document: ...
|
|
||||||
def delete(self, id: str) -> None: ...
|
// Avoid service locator pattern
|
||||||
|
// Bad: var service = serviceProvider.GetService<IMyService>();
|
||||||
|
// Good: Constructor injection
|
||||||
```
|
```
|
||||||
|
|
||||||
### Service Layer
|
## Entity Framework Core
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
class InferenceService:
|
// Always use AsNoTracking for read-only queries
|
||||||
def __init__(self, model_path: str, use_gpu: bool = True):
|
await _context.Documents.AsNoTracking().ToListAsync(ct);
|
||||||
self.pipeline = InferencePipeline(model_path=model_path, use_gpu=use_gpu)
|
|
||||||
|
|
||||||
async def process(self, file: UploadFile, confidence_threshold: float) -> InferenceResult:
|
// Use projection to select only needed fields
|
||||||
temp_path = self._save_temp_file(file)
|
await _context.Documents
|
||||||
try:
|
.Where(d => d.Status == "Active")
|
||||||
return self.pipeline.process_pdf(temp_path)
|
.Select(d => new DocumentDto(d.Id, d.Name))
|
||||||
finally:
|
.ToListAsync(ct);
|
||||||
temp_path.unlink(missing_ok=True)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Dependency Injection
|
// Prevent N+1 with Include or projection
|
||||||
|
await _context.Documents.Include(d => d.Labels).ToListAsync(ct);
|
||||||
|
|
||||||
```python
|
// Use explicit transactions for multiple operations
|
||||||
from functools import lru_cache
|
await using var tx = await _context.Database.BeginTransactionAsync(ct);
|
||||||
from pydantic_settings import BaseSettings
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
// Configure entities with IEntityTypeConfiguration
|
||||||
db_host: str = "localhost"
|
public class DocumentConfiguration : IEntityTypeConfiguration<Document>
|
||||||
db_password: str
|
{
|
||||||
model_path: str = "runs/train/invoice_fields/weights/best.pt"
|
public void Configure(EntityTypeBuilder<Document> builder)
|
||||||
class Config:
|
{
|
||||||
env_file = ".env"
|
builder.HasKey(d => d.Id);
|
||||||
|
builder.Property(d => d.Name).HasMaxLength(200).IsRequired();
|
||||||
@lru_cache()
|
builder.HasIndex(d => d.Status);
|
||||||
def get_settings() -> Settings:
|
}
|
||||||
return Settings()
|
}
|
||||||
|
|
||||||
def get_inference_service(settings: Settings = Depends(get_settings)) -> InferenceService:
|
|
||||||
return InferenceService(model_path=settings.model_path)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Database Patterns
|
|
||||||
|
|
||||||
### Connection Pooling
|
|
||||||
|
|
||||||
```python
|
|
||||||
from psycopg2 import pool
|
|
||||||
from contextlib import contextmanager
|
|
||||||
|
|
||||||
db_pool = pool.ThreadedConnectionPool(minconn=2, maxconn=10, **db_config)
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = db_pool.getconn()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
db_pool.putconn(conn)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Query Optimization
|
|
||||||
|
|
||||||
```python
|
|
||||||
# GOOD: Select only needed columns
|
|
||||||
cur.execute("""
|
|
||||||
SELECT id, status, fields->>'InvoiceNumber' as invoice_number
|
|
||||||
FROM documents WHERE status = %s
|
|
||||||
ORDER BY created_at DESC LIMIT %s
|
|
||||||
""", ('processed', 10))
|
|
||||||
|
|
||||||
# BAD: SELECT * FROM documents
|
|
||||||
```
|
|
||||||
|
|
||||||
### N+1 Prevention
|
|
||||||
|
|
||||||
```python
|
|
||||||
# BAD: N+1 queries
|
|
||||||
for doc in documents:
|
|
||||||
doc.labels = get_labels(doc.id) # N queries
|
|
||||||
|
|
||||||
# GOOD: Batch fetch with JOIN
|
|
||||||
cur.execute("""
|
|
||||||
SELECT d.id, d.status, array_agg(l.label) as labels
|
|
||||||
FROM documents d
|
|
||||||
LEFT JOIN document_labels l ON d.id = l.document_id
|
|
||||||
GROUP BY d.id, d.status
|
|
||||||
""")
|
|
||||||
```
|
|
||||||
|
|
||||||
### Transaction Pattern
|
|
||||||
|
|
||||||
```python
|
|
||||||
def create_document_with_labels(doc_data: dict, labels: list[dict]) -> str:
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
try:
|
|
||||||
with conn.cursor() as cur:
|
|
||||||
cur.execute("INSERT INTO documents ... RETURNING id", ...)
|
|
||||||
doc_id = cur.fetchone()[0]
|
|
||||||
for label in labels:
|
|
||||||
cur.execute("INSERT INTO document_labels ...", ...)
|
|
||||||
conn.commit()
|
|
||||||
return doc_id
|
|
||||||
except Exception:
|
|
||||||
conn.rollback()
|
|
||||||
raise
|
|
||||||
```
|
|
||||||
|
|
||||||
## Caching
|
|
||||||
|
|
||||||
```python
|
|
||||||
from cachetools import TTLCache
|
|
||||||
|
|
||||||
_cache = TTLCache(maxsize=1000, ttl=300)
|
|
||||||
|
|
||||||
def get_document_cached(doc_id: str) -> Document | None:
|
|
||||||
if doc_id in _cache:
|
|
||||||
return _cache[doc_id]
|
|
||||||
doc = repo.find_by_id(doc_id)
|
|
||||||
if doc:
|
|
||||||
_cache[doc_id] = doc
|
|
||||||
return doc
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Error Handling
|
## Error Handling
|
||||||
|
|
||||||
### Exception Hierarchy
|
```csharp
|
||||||
|
// Create domain-specific exceptions
|
||||||
|
public class NotFoundException(string resource, Guid id)
|
||||||
|
: Exception($"{resource} not found: {id}");
|
||||||
|
|
||||||
```python
|
// Use global exception handler
|
||||||
class AppError(Exception):
|
public class GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger) : IExceptionHandler
|
||||||
def __init__(self, message: str, status_code: int = 500):
|
{
|
||||||
self.message = message
|
public async ValueTask<bool> TryHandleAsync(HttpContext ctx, Exception ex, CancellationToken ct)
|
||||||
self.status_code = status_code
|
{
|
||||||
|
logger.LogError(ex, "Error: {Message}", ex.Message);
|
||||||
|
ctx.Response.StatusCode = ex is NotFoundException ? 404 : 500;
|
||||||
|
await ctx.Response.WriteAsJsonAsync(new { error = ex.Message }, ct);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class NotFoundError(AppError):
|
// Use Result pattern for expected failures
|
||||||
def __init__(self, resource: str, id: str):
|
public Result<Document> Validate(CreateRequest request) =>
|
||||||
super().__init__(f"{resource} not found: {id}", 404)
|
string.IsNullOrEmpty(request.Name)
|
||||||
|
? Result<Document>.Fail("Name is required")
|
||||||
class ValidationError(AppError):
|
: Result<Document>.Ok(new Document(request.Name));
|
||||||
def __init__(self, message: str):
|
|
||||||
super().__init__(message, 400)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### FastAPI Exception Handler
|
## Validation
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
@app.exception_handler(AppError)
|
// Use FluentValidation
|
||||||
async def app_error_handler(request: Request, exc: AppError):
|
public class CreateDocumentValidator : AbstractValidator<CreateDocumentRequest>
|
||||||
return JSONResponse(status_code=exc.status_code, content={"success": False, "error": exc.message})
|
{
|
||||||
|
public CreateDocumentValidator()
|
||||||
|
{
|
||||||
|
RuleFor(x => x.Name).NotEmpty().MaximumLength(200);
|
||||||
|
RuleFor(x => x.Type).Must(BeValidType).WithMessage("Invalid document type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@app.exception_handler(Exception)
|
// Or use Data Annotations for simple cases
|
||||||
async def generic_error_handler(request: Request, exc: Exception):
|
public record CreateRequest(
|
||||||
logger.error(f"Unexpected error: {exc}", exc_info=True)
|
[Required, MaxLength(200)] string Name,
|
||||||
return JSONResponse(status_code=500, content={"success": False, "error": "Internal server error"})
|
[Range(1, 100)] int Quantity);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Retry with Backoff
|
## Logging
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
async def retry_with_backoff(fn, max_retries: int = 3, base_delay: float = 1.0):
|
// Use structured logging with templates
|
||||||
last_error = None
|
logger.LogInformation("Processing document {DocumentId} for user {UserId}", docId, userId);
|
||||||
for attempt in range(max_retries):
|
|
||||||
try:
|
// Use appropriate log levels
|
||||||
return await fn() if asyncio.iscoroutinefunction(fn) else fn()
|
logger.LogDebug("Cache hit for key {Key}", key); // Development details
|
||||||
except Exception as e:
|
logger.LogInformation("Document {Id} created", id); // Normal operations
|
||||||
last_error = e
|
logger.LogWarning("Retry attempt {Attempt} for {Op}", n, op); // Potential issues
|
||||||
if attempt < max_retries - 1:
|
logger.LogError(ex, "Failed to process {DocumentId}", id); // Errors
|
||||||
await asyncio.sleep(base_delay * (2 ** attempt))
|
|
||||||
raise last_error
|
// Configure log filtering in appsettings
|
||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning",
|
||||||
|
"Microsoft.EntityFrameworkCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Rate Limiting
|
## API Design
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
from time import time
|
[ApiController]
|
||||||
from collections import defaultdict
|
[Route("api/v1/[controller]")]
|
||||||
|
public class DocumentsController(IDocumentService service) : ControllerBase
|
||||||
|
{
|
||||||
|
[HttpGet("{id:guid}")]
|
||||||
|
[ProducesResponseType<Document>(200)]
|
||||||
|
[ProducesResponseType(404)]
|
||||||
|
public async Task<IActionResult> Get(Guid id, CancellationToken ct)
|
||||||
|
{
|
||||||
|
var doc = await service.GetAsync(id, ct);
|
||||||
|
return doc is null ? NotFound() : Ok(doc);
|
||||||
|
}
|
||||||
|
|
||||||
class RateLimiter:
|
[HttpPost]
|
||||||
def __init__(self):
|
public async Task<IActionResult> Create(CreateRequest request, CancellationToken ct)
|
||||||
self.requests: dict[str, list[float]] = defaultdict(list)
|
{
|
||||||
|
var doc = await service.CreateAsync(request, ct);
|
||||||
def check_limit(self, identifier: str, max_requests: int, window_sec: int) -> bool:
|
return CreatedAtAction(nameof(Get), new { id = doc.Id }, doc);
|
||||||
now = time()
|
}
|
||||||
self.requests[identifier] = [t for t in self.requests[identifier] if now - t < window_sec]
|
}
|
||||||
if len(self.requests[identifier]) >= max_requests:
|
|
||||||
return False
|
|
||||||
self.requests[identifier].append(now)
|
|
||||||
return True
|
|
||||||
|
|
||||||
limiter = RateLimiter()
|
|
||||||
|
|
||||||
@app.middleware("http")
|
|
||||||
async def rate_limit_middleware(request: Request, call_next):
|
|
||||||
ip = request.client.host
|
|
||||||
if not limiter.check_limit(ip, max_requests=100, window_sec=60):
|
|
||||||
return JSONResponse(status_code=429, content={"error": "Rate limit exceeded"})
|
|
||||||
return await call_next(request)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Logging & Middleware
|
## Testing
|
||||||
|
|
||||||
### Request Logging
|
```csharp
|
||||||
|
// Use descriptive test names
|
||||||
|
[Fact]
|
||||||
|
public async Task GetById_WithValidId_ReturnsDocument()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var repo = Substitute.For<IRepository<Document>>();
|
||||||
|
repo.GetByIdAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>())
|
||||||
|
.Returns(new Document("Test"));
|
||||||
|
var service = new DocumentService(repo);
|
||||||
|
|
||||||
```python
|
// Act
|
||||||
@app.middleware("http")
|
var result = await service.GetAsync(Guid.NewGuid(), CancellationToken.None);
|
||||||
async def log_requests(request: Request, call_next):
|
|
||||||
request_id = str(uuid.uuid4())[:8]
|
// Assert
|
||||||
start_time = time.time()
|
result.Should().NotBeNull();
|
||||||
logger.info(f"[{request_id}] {request.method} {request.url.path}")
|
result!.Name.Should().Be("Test");
|
||||||
response = await call_next(request)
|
}
|
||||||
duration_ms = (time.time() - start_time) * 1000
|
|
||||||
logger.info(f"[{request_id}] Completed {response.status_code} in {duration_ms:.2f}ms")
|
// Use WebApplicationFactory for integration tests
|
||||||
return response
|
public class ApiTests(WebApplicationFactory<Program> factory) : IClassFixture<WebApplicationFactory<Program>>
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task GetDocuments_ReturnsSuccess()
|
||||||
|
{
|
||||||
|
var client = factory.CreateClient();
|
||||||
|
var response = await client.GetAsync("/api/v1/documents");
|
||||||
|
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Structured Logging
|
## Performance
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
class JSONFormatter(logging.Formatter):
|
// Use IMemoryCache for frequently accessed data
|
||||||
def format(self, record):
|
public class CachedService(IMemoryCache cache, IRepository<Document> repo)
|
||||||
return json.dumps({
|
{
|
||||||
"timestamp": datetime.utcnow().isoformat(),
|
public async Task<Document?> GetAsync(Guid id, CancellationToken ct) =>
|
||||||
"level": record.levelname,
|
await cache.GetOrCreateAsync($"doc:{id}", async entry =>
|
||||||
"message": record.getMessage(),
|
{
|
||||||
"module": record.module,
|
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5);
|
||||||
})
|
return await repo.GetByIdAsync(id, ct);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use pagination for large collections
|
||||||
|
public async Task<PagedResult<Document>> GetPagedAsync(int page, int size, CancellationToken ct) =>
|
||||||
|
new(
|
||||||
|
await _context.Documents.Skip((page - 1) * size).Take(size).ToListAsync(ct),
|
||||||
|
await _context.Documents.CountAsync(ct)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Use IAsyncEnumerable for streaming large datasets
|
||||||
|
public async IAsyncEnumerable<Document> StreamAllAsync([EnumeratorCancellation] CancellationToken ct)
|
||||||
|
{
|
||||||
|
await foreach (var doc in _context.Documents.AsAsyncEnumerable().WithCancellation(ct))
|
||||||
|
yield return doc;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Background Tasks
|
## Security
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
from fastapi import BackgroundTasks
|
// Never hardcode secrets
|
||||||
|
var apiKey = builder.Configuration["ApiKey"]; // From environment/secrets
|
||||||
|
|
||||||
def send_notification(document_id: str, status: str):
|
// Use parameterized queries (EF Core does this automatically)
|
||||||
logger.info(f"Notification: {document_id} -> {status}")
|
// Bad: $"SELECT * FROM Users WHERE Id = {id}"
|
||||||
|
// Good: _context.Users.Where(u => u.Id == id)
|
||||||
|
|
||||||
@router.post("/infer")
|
// Validate and sanitize all inputs
|
||||||
async def infer(file: UploadFile, background_tasks: BackgroundTasks):
|
// Use HTTPS in production
|
||||||
result = await process_document(file)
|
// Implement rate limiting
|
||||||
background_tasks.add_task(send_notification, result.document_id, "completed")
|
builder.Services.AddRateLimiter(options => { ... });
|
||||||
return result
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Key Principles
|
|
||||||
|
|
||||||
- Repository pattern: Abstract data access
|
|
||||||
- Service layer: Business logic separated from routes
|
|
||||||
- Dependency injection via `Depends()`
|
|
||||||
- Connection pooling for database
|
|
||||||
- Parameterized queries only (no f-strings in SQL)
|
|
||||||
- Batch fetch to prevent N+1
|
|
||||||
- Consistent `ApiResponse[T]` format
|
|
||||||
- Exception hierarchy with proper status codes
|
|
||||||
- Rate limit by IP
|
|
||||||
- Structured logging with request ID
|
|
||||||
@@ -1,665 +1,234 @@
|
|||||||
---
|
---
|
||||||
name: coding-standards
|
name: coding-standards
|
||||||
description: Universal coding standards, best practices, and patterns for Python, FastAPI, and data processing development.
|
description: .NET/C# coding standards and best practices.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Coding Standards & Best Practices
|
# .NET Coding Standards
|
||||||
|
|
||||||
Python coding standards for the Invoice Master project.
|
## Core Principles
|
||||||
|
|
||||||
## Code Quality Principles
|
- **Readability First** - Clear names, self-documenting code
|
||||||
|
- **KISS** - Simplest solution that works
|
||||||
|
- **DRY** - Extract common logic, avoid copy-paste
|
||||||
|
- **YAGNI** - Don't build features before needed
|
||||||
|
|
||||||
### 1. Readability First
|
## Naming Conventions
|
||||||
- Code is read more than written
|
|
||||||
- Clear variable and function names
|
|
||||||
- Self-documenting code preferred over comments
|
|
||||||
- Consistent formatting (follow PEP 8)
|
|
||||||
|
|
||||||
### 2. KISS (Keep It Simple, Stupid)
|
```csharp
|
||||||
- Simplest solution that works
|
// PascalCase: Types, methods, properties, public fields
|
||||||
- Avoid over-engineering
|
public class DocumentService { }
|
||||||
- No premature optimization
|
public async Task<Document> GetByIdAsync(Guid id) { }
|
||||||
- Easy to understand > clever code
|
public string InvoiceNumber { get; init; }
|
||||||
|
|
||||||
### 3. DRY (Don't Repeat Yourself)
|
// camelCase: Parameters, local variables, private fields with underscore
|
||||||
- Extract common logic into functions
|
private readonly ILogger<DocumentService> _logger;
|
||||||
- Create reusable utilities
|
public void Process(string documentId, int pageCount) { }
|
||||||
- Share modules across the codebase
|
|
||||||
- Avoid copy-paste programming
|
|
||||||
|
|
||||||
### 4. YAGNI (You Aren't Gonna Need It)
|
// Interfaces: I prefix
|
||||||
- Don't build features before they're needed
|
public interface IDocumentRepository { }
|
||||||
- Avoid speculative generality
|
|
||||||
- Add complexity only when required
|
|
||||||
- Start simple, refactor when needed
|
|
||||||
|
|
||||||
## Python Standards
|
// Async methods: Async suffix
|
||||||
|
public async Task<Document> LoadAsync(CancellationToken ct)
|
||||||
### Variable Naming
|
|
||||||
|
|
||||||
```python
|
|
||||||
# GOOD: Descriptive names
|
|
||||||
invoice_number = "INV-2024-001"
|
|
||||||
is_valid_document = True
|
|
||||||
total_confidence_score = 0.95
|
|
||||||
|
|
||||||
# BAD: Unclear names
|
|
||||||
inv = "INV-2024-001"
|
|
||||||
flag = True
|
|
||||||
x = 0.95
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Function Naming
|
## Modern C# Features
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
# GOOD: Verb-noun pattern with type hints
|
// Records for DTOs and value objects
|
||||||
def extract_invoice_fields(pdf_path: Path) -> dict[str, str]:
|
public sealed record CreateDocumentRequest(string Name, string Type);
|
||||||
"""Extract fields from invoice PDF."""
|
public sealed record DocumentDto(Guid Id, string Name, DateTime CreatedAt);
|
||||||
...
|
|
||||||
|
|
||||||
def calculate_confidence(predictions: list[float]) -> float:
|
// Primary constructors
|
||||||
"""Calculate average confidence score."""
|
public class DocumentService(IRepository<Document> repo, ILogger<DocumentService> logger)
|
||||||
...
|
{
|
||||||
|
public async Task<Document?> GetAsync(Guid id, CancellationToken ct) =>
|
||||||
|
await repo.GetByIdAsync(id, ct);
|
||||||
|
}
|
||||||
|
|
||||||
def is_valid_bankgiro(value: str) -> bool:
|
// Pattern matching
|
||||||
"""Check if value is valid Bankgiro number."""
|
var message = result switch
|
||||||
...
|
{
|
||||||
|
{ IsSuccess: true, Value: var doc } => $"Found: {doc.Name}",
|
||||||
|
{ Error: var err } => $"Error: {err}",
|
||||||
|
_ => "Unknown"
|
||||||
|
};
|
||||||
|
|
||||||
# BAD: Unclear or noun-only
|
// Collection expressions
|
||||||
def invoice(path):
|
int[] numbers = [1, 2, 3];
|
||||||
...
|
List<string> names = ["Alice", "Bob"];
|
||||||
|
|
||||||
def confidence(p):
|
// Null coalescing
|
||||||
...
|
var name = user?.Name ?? "Unknown";
|
||||||
|
list ??= [];
|
||||||
def bankgiro(v):
|
|
||||||
...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Type Hints (REQUIRED)
|
## Immutability (Critical)
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
# GOOD: Full type annotations
|
// GOOD: Create new objects
|
||||||
from typing import Optional
|
public record User(string Name, int Age)
|
||||||
from pathlib import Path
|
{
|
||||||
from dataclasses import dataclass
|
public User WithName(string newName) => this with { Name = newName };
|
||||||
|
}
|
||||||
|
|
||||||
@dataclass
|
// GOOD: Immutable collections
|
||||||
class InferenceResult:
|
public IReadOnlyList<string> GetNames() => _names.AsReadOnly();
|
||||||
document_id: str
|
|
||||||
fields: dict[str, str]
|
|
||||||
confidence: dict[str, float]
|
|
||||||
processing_time_ms: float
|
|
||||||
|
|
||||||
def process_document(
|
// BAD: Mutation
|
||||||
pdf_path: Path,
|
public void UpdateUser(User user, string name)
|
||||||
confidence_threshold: float = 0.5
|
{
|
||||||
) -> InferenceResult:
|
user.Name = name; // MUTATION!
|
||||||
"""Process PDF and return extracted fields."""
|
}
|
||||||
...
|
|
||||||
|
|
||||||
# BAD: No type hints
|
|
||||||
def process_document(pdf_path, confidence_threshold=0.5):
|
|
||||||
...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Immutability Pattern (CRITICAL)
|
## Error Handling
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
# GOOD: Create new objects, don't mutate
|
// Domain exceptions
|
||||||
def update_fields(fields: dict[str, str], updates: dict[str, str]) -> dict[str, str]:
|
public class NotFoundException(string resource, Guid id)
|
||||||
return {**fields, **updates}
|
: Exception($"{resource} not found: {id}");
|
||||||
|
|
||||||
def add_item(items: list[str], new_item: str) -> list[str]:
|
// Comprehensive handling
|
||||||
return [*items, new_item]
|
public async Task<Document> LoadAsync(Guid id, CancellationToken ct)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var doc = await _repo.GetByIdAsync(id, ct);
|
||||||
|
return doc ?? throw new NotFoundException("Document", id);
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (ex is not NotFoundException)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Failed to load document {Id}", id);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# BAD: Direct mutation
|
// Result pattern for expected failures
|
||||||
def update_fields(fields: dict[str, str], updates: dict[str, str]) -> dict[str, str]:
|
public Result<Document> Validate(CreateRequest request) =>
|
||||||
fields.update(updates) # MUTATION!
|
string.IsNullOrEmpty(request.Name)
|
||||||
return fields
|
? Result<Document>.Fail("Name required")
|
||||||
|
: Result<Document>.Ok(new Document(request.Name));
|
||||||
def add_item(items: list[str], new_item: str) -> list[str]:
|
|
||||||
items.append(new_item) # MUTATION!
|
|
||||||
return items
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Error Handling
|
## Async/Await
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
import logging
|
// Always pass CancellationToken
|
||||||
|
public async Task<Document> GetAsync(Guid id, CancellationToken ct)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
// Use ConfigureAwait(false) in libraries
|
||||||
|
await _client.GetAsync(url, ct).ConfigureAwait(false);
|
||||||
|
|
||||||
# GOOD: Comprehensive error handling with logging
|
// Avoid async void
|
||||||
def load_model(model_path: Path) -> Model:
|
public async Task ProcessAsync() { } // Good
|
||||||
"""Load YOLO model from path."""
|
public async void Process() { } // Bad
|
||||||
try:
|
|
||||||
if not model_path.exists():
|
|
||||||
raise FileNotFoundError(f"Model not found: {model_path}")
|
|
||||||
|
|
||||||
model = YOLO(str(model_path))
|
// Parallel when independent
|
||||||
logger.info(f"Model loaded: {model_path}")
|
var tasks = ids.Select(id => GetAsync(id, ct));
|
||||||
return model
|
var results = await Task.WhenAll(tasks);
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Failed to load model: {e}")
|
|
||||||
raise RuntimeError(f"Model loading failed: {model_path}") from e
|
|
||||||
|
|
||||||
# BAD: No error handling
|
|
||||||
def load_model(model_path):
|
|
||||||
return YOLO(str(model_path))
|
|
||||||
|
|
||||||
# BAD: Bare except
|
|
||||||
def load_model(model_path):
|
|
||||||
try:
|
|
||||||
return YOLO(str(model_path))
|
|
||||||
except: # Never use bare except!
|
|
||||||
return None
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Async Best Practices
|
## LINQ Best Practices
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
import asyncio
|
// Prefer method syntax for complex queries
|
||||||
|
var result = documents
|
||||||
|
.Where(d => d.Status == "Active")
|
||||||
|
.OrderByDescending(d => d.CreatedAt)
|
||||||
|
.Select(d => new DocumentDto(d.Id, d.Name, d.CreatedAt))
|
||||||
|
.Take(10);
|
||||||
|
|
||||||
# GOOD: Parallel execution when possible
|
// Use Any() instead of Count() > 0
|
||||||
async def process_batch(pdf_paths: list[Path]) -> list[InferenceResult]:
|
if (documents.Any(d => d.IsValid)) { }
|
||||||
tasks = [process_document(path) for path in pdf_paths]
|
|
||||||
results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
||||||
|
|
||||||
# Handle exceptions
|
// Avoid multiple enumerations
|
||||||
valid_results = []
|
var list = documents.ToList(); // Materialize once
|
||||||
for path, result in zip(pdf_paths, results):
|
var count = list.Count;
|
||||||
if isinstance(result, Exception):
|
var first = list.FirstOrDefault();
|
||||||
logger.error(f"Failed to process {path}: {result}")
|
|
||||||
else:
|
|
||||||
valid_results.append(result)
|
|
||||||
return valid_results
|
|
||||||
|
|
||||||
# BAD: Sequential when unnecessary
|
|
||||||
async def process_batch(pdf_paths: list[Path]) -> list[InferenceResult]:
|
|
||||||
results = []
|
|
||||||
for path in pdf_paths:
|
|
||||||
result = await process_document(path)
|
|
||||||
results.append(result)
|
|
||||||
return results
|
|
||||||
```
|
|
||||||
|
|
||||||
### Context Managers
|
|
||||||
|
|
||||||
```python
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from pathlib import Path
|
|
||||||
import tempfile
|
|
||||||
|
|
||||||
# GOOD: Proper resource management
|
|
||||||
@contextmanager
|
|
||||||
def temp_pdf_copy(pdf_path: Path):
|
|
||||||
"""Create temporary copy of PDF for processing."""
|
|
||||||
with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as tmp:
|
|
||||||
tmp.write(pdf_path.read_bytes())
|
|
||||||
tmp_path = Path(tmp.name)
|
|
||||||
try:
|
|
||||||
yield tmp_path
|
|
||||||
finally:
|
|
||||||
tmp_path.unlink(missing_ok=True)
|
|
||||||
|
|
||||||
# Usage
|
|
||||||
with temp_pdf_copy(original_pdf) as tmp_pdf:
|
|
||||||
result = process_pdf(tmp_pdf)
|
|
||||||
```
|
|
||||||
|
|
||||||
## FastAPI Best Practices
|
|
||||||
|
|
||||||
### Route Structure
|
|
||||||
|
|
||||||
```python
|
|
||||||
from fastapi import APIRouter, HTTPException, Depends, Query, File, UploadFile
|
|
||||||
from pydantic import BaseModel
|
|
||||||
|
|
||||||
router = APIRouter(prefix="/api/v1", tags=["inference"])
|
|
||||||
|
|
||||||
class InferenceResponse(BaseModel):
|
|
||||||
success: bool
|
|
||||||
document_id: str
|
|
||||||
fields: dict[str, str]
|
|
||||||
confidence: dict[str, float]
|
|
||||||
processing_time_ms: float
|
|
||||||
|
|
||||||
@router.post("/infer", response_model=InferenceResponse)
|
|
||||||
async def infer_document(
|
|
||||||
file: UploadFile = File(...),
|
|
||||||
confidence_threshold: float = Query(0.5, ge=0.0, le=1.0)
|
|
||||||
) -> InferenceResponse:
|
|
||||||
"""Process invoice PDF and extract fields."""
|
|
||||||
if not file.filename.endswith(".pdf"):
|
|
||||||
raise HTTPException(status_code=400, detail="Only PDF files accepted")
|
|
||||||
|
|
||||||
result = await inference_service.process(file, confidence_threshold)
|
|
||||||
return InferenceResponse(
|
|
||||||
success=True,
|
|
||||||
document_id=result.document_id,
|
|
||||||
fields=result.fields,
|
|
||||||
confidence=result.confidence,
|
|
||||||
processing_time_ms=result.processing_time_ms
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Input Validation with Pydantic
|
|
||||||
|
|
||||||
```python
|
|
||||||
from pydantic import BaseModel, Field, field_validator
|
|
||||||
from datetime import date
|
|
||||||
import re
|
|
||||||
|
|
||||||
class InvoiceData(BaseModel):
|
|
||||||
invoice_number: str = Field(..., min_length=1, max_length=50)
|
|
||||||
invoice_date: date
|
|
||||||
amount: float = Field(..., gt=0)
|
|
||||||
bankgiro: str | None = None
|
|
||||||
ocr_number: str | None = None
|
|
||||||
|
|
||||||
@field_validator("bankgiro")
|
|
||||||
@classmethod
|
|
||||||
def validate_bankgiro(cls, v: str | None) -> str | None:
|
|
||||||
if v is None:
|
|
||||||
return None
|
|
||||||
# Bankgiro: 7-8 digits
|
|
||||||
cleaned = re.sub(r"[^0-9]", "", v)
|
|
||||||
if not (7 <= len(cleaned) <= 8):
|
|
||||||
raise ValueError("Bankgiro must be 7-8 digits")
|
|
||||||
return cleaned
|
|
||||||
|
|
||||||
@field_validator("ocr_number")
|
|
||||||
@classmethod
|
|
||||||
def validate_ocr(cls, v: str | None) -> str | None:
|
|
||||||
if v is None:
|
|
||||||
return None
|
|
||||||
# OCR: 2-25 digits
|
|
||||||
cleaned = re.sub(r"[^0-9]", "", v)
|
|
||||||
if not (2 <= len(cleaned) <= 25):
|
|
||||||
raise ValueError("OCR must be 2-25 digits")
|
|
||||||
return cleaned
|
|
||||||
```
|
|
||||||
|
|
||||||
### Response Format
|
|
||||||
|
|
||||||
```python
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import Generic, TypeVar
|
|
||||||
|
|
||||||
T = TypeVar("T")
|
|
||||||
|
|
||||||
class ApiResponse(BaseModel, Generic[T]):
|
|
||||||
success: bool
|
|
||||||
data: T | None = None
|
|
||||||
error: str | None = None
|
|
||||||
meta: dict | None = None
|
|
||||||
|
|
||||||
# Success response
|
|
||||||
return ApiResponse(
|
|
||||||
success=True,
|
|
||||||
data=result,
|
|
||||||
meta={"processing_time_ms": elapsed_ms}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Error response
|
|
||||||
return ApiResponse(
|
|
||||||
success=False,
|
|
||||||
error="Invalid PDF format"
|
|
||||||
)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## File Organization
|
## File Organization
|
||||||
|
|
||||||
### Project Structure
|
|
||||||
|
|
||||||
```
|
```
|
||||||
src/
|
src/
|
||||||
├── cli/ # Command-line interfaces
|
Domain/ # Entities, value objects
|
||||||
│ ├── autolabel.py
|
Application/ # Use cases, DTOs, interfaces
|
||||||
│ ├── train.py
|
Infrastructure/ # EF Core, external services
|
||||||
│ └── infer.py
|
Api/ # Controllers, middleware
|
||||||
├── pdf/ # PDF processing
|
tests/
|
||||||
│ ├── extractor.py
|
Unit/
|
||||||
│ └── renderer.py
|
Integration/
|
||||||
├── ocr/ # OCR processing
|
|
||||||
│ ├── paddle_ocr.py
|
|
||||||
│ └── machine_code_parser.py
|
|
||||||
├── inference/ # Inference pipeline
|
|
||||||
│ ├── pipeline.py
|
|
||||||
│ ├── yolo_detector.py
|
|
||||||
│ └── field_extractor.py
|
|
||||||
├── normalize/ # Field normalization
|
|
||||||
│ ├── base.py
|
|
||||||
│ ├── date_normalizer.py
|
|
||||||
│ └── amount_normalizer.py
|
|
||||||
├── web/ # FastAPI application
|
|
||||||
│ ├── app.py
|
|
||||||
│ ├── routes.py
|
|
||||||
│ ├── services.py
|
|
||||||
│ └── schemas.py
|
|
||||||
└── utils/ # Shared utilities
|
|
||||||
├── validators.py
|
|
||||||
├── text_cleaner.py
|
|
||||||
└── logging.py
|
|
||||||
tests/ # Mirror of src structure
|
|
||||||
├── test_pdf/
|
|
||||||
├── test_ocr/
|
|
||||||
└── test_inference/
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### File Naming
|
**Guidelines:**
|
||||||
|
- Max 800 lines per file (typical 200-400)
|
||||||
|
- Max 50 lines per method
|
||||||
|
- One class per file (except nested)
|
||||||
|
- Group by feature, not by type
|
||||||
|
|
||||||
```
|
## Code Smells
|
||||||
src/ocr/paddle_ocr.py # snake_case for modules
|
|
||||||
src/inference/yolo_detector.py # snake_case for modules
|
```csharp
|
||||||
tests/test_paddle_ocr.py # test_ prefix for tests
|
// BAD: Deep nesting
|
||||||
config.py # snake_case for config
|
if (doc != null)
|
||||||
|
if (doc.IsValid)
|
||||||
|
if (doc.HasFields)
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// GOOD: Early returns
|
||||||
|
if (doc is null) return null;
|
||||||
|
if (!doc.IsValid) return null;
|
||||||
|
if (!doc.HasFields) return null;
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// BAD: Magic numbers
|
||||||
|
if (confidence > 0.5) { }
|
||||||
|
|
||||||
|
// GOOD: Named constants
|
||||||
|
private const double ConfidenceThreshold = 0.5;
|
||||||
|
if (confidence > ConfidenceThreshold) { }
|
||||||
```
|
```
|
||||||
|
|
||||||
### Module Size Guidelines
|
## Logging
|
||||||
|
|
||||||
- **Maximum**: 800 lines per file
|
```csharp
|
||||||
- **Typical**: 200-400 lines per file
|
// Structured logging with templates
|
||||||
- **Functions**: Max 50 lines each
|
_logger.LogInformation("Processing document {DocumentId}", docId);
|
||||||
- Extract utilities when modules grow too large
|
_logger.LogError(ex, "Failed to process {DocumentId}", docId);
|
||||||
|
|
||||||
## Comments & Documentation
|
// Appropriate levels
|
||||||
|
LogDebug // Development details
|
||||||
### When to Comment
|
LogInformation // Normal operations
|
||||||
|
LogWarning // Potential issues
|
||||||
```python
|
LogError // Errors with exceptions
|
||||||
# GOOD: Explain WHY, not WHAT
|
|
||||||
# Swedish Bankgiro uses Luhn algorithm with weight [1,2,1,2...]
|
|
||||||
def validate_bankgiro_checksum(bankgiro: str) -> bool:
|
|
||||||
...
|
|
||||||
|
|
||||||
# Payment line format: 7 groups separated by #, checksum at end
|
|
||||||
def parse_payment_line(line: str) -> PaymentLineData:
|
|
||||||
...
|
|
||||||
|
|
||||||
# BAD: Stating the obvious
|
|
||||||
# Increment counter by 1
|
|
||||||
count += 1
|
|
||||||
|
|
||||||
# Set name to user's name
|
|
||||||
name = user.name
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Docstrings for Public APIs
|
## Testing (AAA Pattern)
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
def extract_invoice_fields(
|
[Fact]
|
||||||
pdf_path: Path,
|
public async Task GetById_WithValidId_ReturnsDocument()
|
||||||
confidence_threshold: float = 0.5,
|
{
|
||||||
use_gpu: bool = True
|
// Arrange
|
||||||
) -> InferenceResult:
|
var repo = Substitute.For<IRepository<Document>>();
|
||||||
"""Extract structured fields from Swedish invoice PDF.
|
repo.GetByIdAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>())
|
||||||
|
.Returns(new Document("Test"));
|
||||||
|
var service = new DocumentService(repo);
|
||||||
|
|
||||||
Uses YOLOv11 for field detection and PaddleOCR for text extraction.
|
// Act
|
||||||
Applies field-specific normalization and validation.
|
var result = await service.GetAsync(Guid.NewGuid(), CancellationToken.None);
|
||||||
|
|
||||||
Args:
|
// Assert
|
||||||
pdf_path: Path to the invoice PDF file.
|
result.Should().NotBeNull();
|
||||||
confidence_threshold: Minimum confidence for field detection (0.0-1.0).
|
result!.Name.Should().Be("Test");
|
||||||
use_gpu: Whether to use GPU acceleration.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
InferenceResult containing extracted fields and confidence scores.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
FileNotFoundError: If PDF file doesn't exist.
|
|
||||||
ProcessingError: If OCR or detection fails.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
>>> result = extract_invoice_fields(Path("invoice.pdf"))
|
|
||||||
>>> print(result.fields["invoice_number"])
|
|
||||||
"INV-2024-001"
|
|
||||||
"""
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Performance Best Practices
|
|
||||||
|
|
||||||
### Caching
|
|
||||||
|
|
||||||
```python
|
|
||||||
from functools import lru_cache
|
|
||||||
from cachetools import TTLCache
|
|
||||||
|
|
||||||
# Static data: LRU cache
|
|
||||||
@lru_cache(maxsize=100)
|
|
||||||
def get_field_config(field_name: str) -> FieldConfig:
|
|
||||||
"""Load field configuration (cached)."""
|
|
||||||
return load_config(field_name)
|
|
||||||
|
|
||||||
# Dynamic data: TTL cache
|
|
||||||
_document_cache = TTLCache(maxsize=1000, ttl=300) # 5 minutes
|
|
||||||
|
|
||||||
def get_document_cached(doc_id: str) -> Document | None:
|
|
||||||
if doc_id in _document_cache:
|
|
||||||
return _document_cache[doc_id]
|
|
||||||
|
|
||||||
doc = repo.find_by_id(doc_id)
|
|
||||||
if doc:
|
|
||||||
_document_cache[doc_id] = doc
|
|
||||||
return doc
|
|
||||||
```
|
|
||||||
|
|
||||||
### Database Queries
|
|
||||||
|
|
||||||
```python
|
|
||||||
# GOOD: Select only needed columns
|
|
||||||
cur.execute("""
|
|
||||||
SELECT id, status, fields->>'invoice_number'
|
|
||||||
FROM documents
|
|
||||||
WHERE status = %s
|
|
||||||
LIMIT %s
|
|
||||||
""", ('processed', 10))
|
|
||||||
|
|
||||||
# BAD: Select everything
|
|
||||||
cur.execute("SELECT * FROM documents")
|
|
||||||
|
|
||||||
# GOOD: Batch operations
|
|
||||||
cur.executemany(
|
|
||||||
"INSERT INTO labels (doc_id, field, value) VALUES (%s, %s, %s)",
|
|
||||||
[(doc_id, f, v) for f, v in fields.items()]
|
|
||||||
)
|
|
||||||
|
|
||||||
# BAD: Individual inserts in loop
|
|
||||||
for field, value in fields.items():
|
|
||||||
cur.execute("INSERT INTO labels ...", (doc_id, field, value))
|
|
||||||
```
|
|
||||||
|
|
||||||
### Lazy Loading
|
|
||||||
|
|
||||||
```python
|
|
||||||
class InferencePipeline:
|
|
||||||
def __init__(self, model_path: Path):
|
|
||||||
self.model_path = model_path
|
|
||||||
self._model: YOLO | None = None
|
|
||||||
self._ocr: PaddleOCR | None = None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def model(self) -> YOLO:
|
|
||||||
"""Lazy load YOLO model."""
|
|
||||||
if self._model is None:
|
|
||||||
self._model = YOLO(str(self.model_path))
|
|
||||||
return self._model
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ocr(self) -> PaddleOCR:
|
|
||||||
"""Lazy load PaddleOCR."""
|
|
||||||
if self._ocr is None:
|
|
||||||
self._ocr = PaddleOCR(use_angle_cls=True, lang="latin")
|
|
||||||
return self._ocr
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing Standards
|
|
||||||
|
|
||||||
### Test Structure (AAA Pattern)
|
|
||||||
|
|
||||||
```python
|
|
||||||
def test_extract_bankgiro_valid():
|
|
||||||
# Arrange
|
|
||||||
text = "Bankgiro: 123-4567"
|
|
||||||
|
|
||||||
# Act
|
|
||||||
result = extract_bankgiro(text)
|
|
||||||
|
|
||||||
# Assert
|
|
||||||
assert result == "1234567"
|
|
||||||
|
|
||||||
def test_extract_bankgiro_invalid_returns_none():
|
|
||||||
# Arrange
|
|
||||||
text = "No bankgiro here"
|
|
||||||
|
|
||||||
# Act
|
|
||||||
result = extract_bankgiro(text)
|
|
||||||
|
|
||||||
# Assert
|
|
||||||
assert result is None
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test Naming
|
|
||||||
|
|
||||||
```python
|
|
||||||
# GOOD: Descriptive test names
|
|
||||||
def test_parse_payment_line_extracts_all_fields(): ...
|
|
||||||
def test_parse_payment_line_handles_missing_checksum(): ...
|
|
||||||
def test_validate_ocr_returns_false_for_invalid_checksum(): ...
|
|
||||||
|
|
||||||
# BAD: Vague test names
|
|
||||||
def test_parse(): ...
|
|
||||||
def test_works(): ...
|
|
||||||
def test_payment_line(): ...
|
|
||||||
```
|
|
||||||
|
|
||||||
### Fixtures
|
|
||||||
|
|
||||||
```python
|
|
||||||
import pytest
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def sample_invoice_pdf(tmp_path: Path) -> Path:
|
|
||||||
"""Create sample invoice PDF for testing."""
|
|
||||||
pdf_path = tmp_path / "invoice.pdf"
|
|
||||||
# Create test PDF...
|
|
||||||
return pdf_path
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def inference_pipeline(sample_model_path: Path) -> InferencePipeline:
|
|
||||||
"""Create inference pipeline with test model."""
|
|
||||||
return InferencePipeline(sample_model_path)
|
|
||||||
|
|
||||||
def test_process_invoice(inference_pipeline, sample_invoice_pdf):
|
|
||||||
result = inference_pipeline.process(sample_invoice_pdf)
|
|
||||||
assert result.fields.get("invoice_number") is not None
|
|
||||||
```
|
|
||||||
|
|
||||||
## Code Smell Detection
|
|
||||||
|
|
||||||
### 1. Long Functions
|
|
||||||
|
|
||||||
```python
|
|
||||||
# BAD: Function > 50 lines
|
|
||||||
def process_document():
|
|
||||||
# 100 lines of code...
|
|
||||||
|
|
||||||
# GOOD: Split into smaller functions
|
|
||||||
def process_document(pdf_path: Path) -> InferenceResult:
|
|
||||||
image = render_pdf(pdf_path)
|
|
||||||
detections = detect_fields(image)
|
|
||||||
ocr_results = extract_text(image, detections)
|
|
||||||
fields = normalize_fields(ocr_results)
|
|
||||||
return build_result(fields)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Deep Nesting
|
|
||||||
|
|
||||||
```python
|
|
||||||
# BAD: 5+ levels of nesting
|
|
||||||
if document:
|
|
||||||
if document.is_valid:
|
|
||||||
if document.has_fields:
|
|
||||||
if field in document.fields:
|
|
||||||
if document.fields[field]:
|
|
||||||
# Do something
|
|
||||||
|
|
||||||
# GOOD: Early returns
|
|
||||||
if not document:
|
|
||||||
return None
|
|
||||||
if not document.is_valid:
|
|
||||||
return None
|
|
||||||
if not document.has_fields:
|
|
||||||
return None
|
|
||||||
if field not in document.fields:
|
|
||||||
return None
|
|
||||||
if not document.fields[field]:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Do something
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Magic Numbers
|
|
||||||
|
|
||||||
```python
|
|
||||||
# BAD: Unexplained numbers
|
|
||||||
if confidence > 0.5:
|
|
||||||
...
|
|
||||||
time.sleep(3)
|
|
||||||
|
|
||||||
# GOOD: Named constants
|
|
||||||
CONFIDENCE_THRESHOLD = 0.5
|
|
||||||
RETRY_DELAY_SECONDS = 3
|
|
||||||
|
|
||||||
if confidence > CONFIDENCE_THRESHOLD:
|
|
||||||
...
|
|
||||||
time.sleep(RETRY_DELAY_SECONDS)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Mutable Default Arguments
|
|
||||||
|
|
||||||
```python
|
|
||||||
# BAD: Mutable default argument
|
|
||||||
def process_fields(fields: list = []): # DANGEROUS!
|
|
||||||
fields.append("new_field")
|
|
||||||
return fields
|
|
||||||
|
|
||||||
# GOOD: Use None as default
|
|
||||||
def process_fields(fields: list | None = None) -> list:
|
|
||||||
if fields is None:
|
|
||||||
fields = []
|
|
||||||
return [*fields, "new_field"]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Logging Standards
|
|
||||||
|
|
||||||
```python
|
|
||||||
import logging
|
|
||||||
|
|
||||||
# Module-level logger
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
# GOOD: Appropriate log levels
|
|
||||||
logger.debug("Processing document: %s", doc_id)
|
|
||||||
logger.info("Document processed successfully: %s", doc_id)
|
|
||||||
logger.warning("Low confidence score: %.2f", confidence)
|
|
||||||
logger.error("Failed to process document: %s", error)
|
|
||||||
|
|
||||||
# GOOD: Structured logging with extra data
|
|
||||||
logger.info(
|
|
||||||
"Inference complete",
|
|
||||||
extra={
|
|
||||||
"document_id": doc_id,
|
|
||||||
"field_count": len(fields),
|
|
||||||
"processing_time_ms": elapsed_ms
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
# BAD: Using print()
|
|
||||||
print(f"Processing {doc_id}") # Never in production!
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Remember**: Code quality is not negotiable. Clear, maintainable Python code with proper type hints enables confident development and refactoring.
|
## Key Rules
|
||||||
|
|
||||||
|
- Always use `CancellationToken` for async methods
|
||||||
|
- Prefer `records` for DTOs and immutable data
|
||||||
|
- Use `IReadOnlyList<T>` for return types
|
||||||
|
- Never use `async void` (except event handlers)
|
||||||
|
- Always handle `null` with pattern matching or null operators
|
||||||
|
- Use structured logging, never `Console.WriteLine`
|
||||||
|
|||||||
151
.gitignore
vendored
151
.gitignore
vendored
@@ -1,26 +1,90 @@
|
|||||||
# Python
|
# .NET / C#
|
||||||
|
## Build outputs
|
||||||
|
bin/
|
||||||
|
obj/
|
||||||
|
out/
|
||||||
|
|
||||||
|
## Visual Studio
|
||||||
|
.vs/
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
## Visual Studio Code
|
||||||
|
.vscode/
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
|
||||||
|
## Rider / IntelliJ
|
||||||
|
.idea/
|
||||||
|
*.sln.iml
|
||||||
|
|
||||||
|
## .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
## ASP.NET Scaffolding
|
||||||
|
ScaffoldingReadMe.txt
|
||||||
|
|
||||||
|
## NuGet
|
||||||
|
*.nupkg
|
||||||
|
*.snupkg
|
||||||
|
.nuget/
|
||||||
|
packages/
|
||||||
|
|
||||||
|
## Test Results
|
||||||
|
TestResults/
|
||||||
|
*.trx
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
## BenchmarkDotNet
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# Frontend (React/Vite)
|
||||||
|
## Dependencies
|
||||||
|
node_modules/
|
||||||
|
.pnp
|
||||||
|
.pnp.js
|
||||||
|
|
||||||
|
## Build outputs
|
||||||
|
dist/
|
||||||
|
dist-ssr/
|
||||||
|
build/
|
||||||
|
*.local
|
||||||
|
|
||||||
|
## Logs
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
## TypeScript
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
## Vite
|
||||||
|
.vite/
|
||||||
|
|
||||||
|
## ESLint
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
## Stylelint
|
||||||
|
.stylelintcache
|
||||||
|
|
||||||
|
# Python (if any scripts)
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
*$py.class
|
*$py.class
|
||||||
*.so
|
*.so
|
||||||
.Python
|
.Python
|
||||||
build/
|
|
||||||
develop-eggs/
|
|
||||||
dist/
|
|
||||||
downloads/
|
|
||||||
eggs/
|
|
||||||
.eggs/
|
|
||||||
lib/
|
|
||||||
lib64/
|
|
||||||
parts/
|
|
||||||
sdist/
|
|
||||||
var/
|
|
||||||
wheels/
|
|
||||||
share/python-wheels/
|
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
.installed.cfg
|
.installed.cfg
|
||||||
*.egg
|
*.egg
|
||||||
MANIFEST
|
|
||||||
|
|
||||||
# Virtual environments
|
# Virtual environments
|
||||||
venv/
|
venv/
|
||||||
@@ -28,13 +92,12 @@ ENV/
|
|||||||
env/
|
env/
|
||||||
.venv
|
.venv
|
||||||
|
|
||||||
# IDEs
|
# IDEs and Editors
|
||||||
.vscode/
|
|
||||||
.idea/
|
|
||||||
*.swp
|
*.swp
|
||||||
*.swo
|
*.swo
|
||||||
*~
|
*~
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
# Environment variables
|
# Environment variables
|
||||||
.env
|
.env
|
||||||
@@ -51,17 +114,9 @@ env/
|
|||||||
*.log
|
*.log
|
||||||
logs/
|
logs/
|
||||||
|
|
||||||
# Testing
|
# Coverage
|
||||||
.coverage
|
coverage/
|
||||||
.pytest_cache/
|
|
||||||
htmlcov/
|
htmlcov/
|
||||||
.tox/
|
|
||||||
.nox/
|
|
||||||
|
|
||||||
# MyPy
|
|
||||||
.mypy_cache/
|
|
||||||
.dmypy.json
|
|
||||||
dmypy.json
|
|
||||||
|
|
||||||
# Terraform
|
# Terraform
|
||||||
.terraform/
|
.terraform/
|
||||||
@@ -71,33 +126,6 @@ dmypy.json
|
|||||||
!.tfvars.example
|
!.tfvars.example
|
||||||
.terraform.lock.hcl
|
.terraform.lock.hcl
|
||||||
|
|
||||||
# Node.js
|
|
||||||
node_modules/
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
.pnpm-debug.log*
|
|
||||||
|
|
||||||
# Build outputs
|
|
||||||
dist/
|
|
||||||
dist-ssr/
|
|
||||||
build/
|
|
||||||
*.local
|
|
||||||
|
|
||||||
# TypeScript
|
|
||||||
*.tsbuildinfo
|
|
||||||
|
|
||||||
# Vite
|
|
||||||
.vite/
|
|
||||||
|
|
||||||
# Coverage
|
|
||||||
coverage/
|
|
||||||
|
|
||||||
# Temporary files
|
|
||||||
*.tmp
|
|
||||||
*.temp
|
|
||||||
.cache/
|
|
||||||
|
|
||||||
# Azure
|
# Azure
|
||||||
azure_credentials.json
|
azure_credentials.json
|
||||||
|
|
||||||
@@ -106,5 +134,16 @@ azure_credentials.json
|
|||||||
*.key
|
*.key
|
||||||
secrets/
|
secrets/
|
||||||
|
|
||||||
# OS
|
# Temporary files
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
|
.cache/
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
desktop.ini
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
*.bak
|
||||||
|
*.orig
|
||||||
|
|||||||
@@ -1,314 +1,274 @@
|
|||||||
# Backend Development Patterns
|
# .NET Development Best Practices
|
||||||
|
|
||||||
Backend architecture patterns for Python/FastAPI/PostgreSQL applications.
|
## Project Structure
|
||||||
|
|
||||||
## API Design
|
|
||||||
|
|
||||||
### RESTful Structure
|
|
||||||
|
|
||||||
```
|
```
|
||||||
GET /api/v1/documents # List
|
src/
|
||||||
GET /api/v1/documents/{id} # Get
|
Domain/ # Entities, value objects, domain events
|
||||||
POST /api/v1/documents # Create
|
Application/ # Use cases, DTOs, interfaces
|
||||||
PUT /api/v1/documents/{id} # Replace
|
Infrastructure/ # EF Core, external services
|
||||||
PATCH /api/v1/documents/{id} # Update
|
Api/ # Controllers, middleware, filters
|
||||||
DELETE /api/v1/documents/{id} # Delete
|
tests/
|
||||||
|
Unit/
|
||||||
GET /api/v1/documents?status=processed&sort=created_at&limit=20&offset=0
|
Integration/
|
||||||
```
|
```
|
||||||
|
|
||||||
### FastAPI Route Pattern
|
## Code Style
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
from fastapi import APIRouter, HTTPException, Depends, Query, File, UploadFile
|
// Use records for DTOs and value objects
|
||||||
from pydantic import BaseModel
|
public sealed record CreateDocumentRequest(string Name, string Type);
|
||||||
|
|
||||||
router = APIRouter(prefix="/api/v1", tags=["inference"])
|
// Use primary constructors
|
||||||
|
public class DocumentService(IRepository<Document> repo, ILogger<DocumentService> logger)
|
||||||
|
{
|
||||||
|
public async Task<Document?> GetAsync(Guid id, CancellationToken ct) =>
|
||||||
|
await repo.GetByIdAsync(id, ct);
|
||||||
|
}
|
||||||
|
|
||||||
@router.post("/infer", response_model=ApiResponse[InferenceResult])
|
// Prefer expression body for simple methods
|
||||||
async def infer_document(
|
public Document? FindById(Guid id) => _documents.FirstOrDefault(d => d.Id == id);
|
||||||
file: UploadFile = File(...),
|
|
||||||
confidence_threshold: float = Query(0.5, ge=0, le=1),
|
// Use collection expressions
|
||||||
service: InferenceService = Depends(get_inference_service)
|
int[] numbers = [1, 2, 3];
|
||||||
) -> ApiResponse[InferenceResult]:
|
List<string> names = ["Alice", "Bob"];
|
||||||
result = await service.process(file, confidence_threshold)
|
|
||||||
return ApiResponse(success=True, data=result)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Consistent Response Schema
|
## Async/Await
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
from typing import Generic, TypeVar
|
// Always pass CancellationToken
|
||||||
T = TypeVar('T')
|
public async Task<Document> GetAsync(Guid id, CancellationToken ct)
|
||||||
|
|
||||||
class ApiResponse(BaseModel, Generic[T]):
|
// Use ConfigureAwait(false) in libraries
|
||||||
success: bool
|
await _httpClient.GetAsync(url, ct).ConfigureAwait(false);
|
||||||
data: T | None = None
|
|
||||||
error: str | None = None
|
// Avoid async void (except event handlers)
|
||||||
meta: dict | None = None
|
public async Task ProcessAsync() { } // Good
|
||||||
|
public async void Process() { } // Bad
|
||||||
|
|
||||||
|
// Use ValueTask for hot paths with frequent sync completion
|
||||||
|
public ValueTask<int> GetCachedCountAsync()
|
||||||
```
|
```
|
||||||
|
|
||||||
## Core Patterns
|
## Dependency Injection
|
||||||
|
|
||||||
### Repository Pattern
|
```csharp
|
||||||
|
// Register by interface
|
||||||
|
builder.Services.AddScoped<IDocumentService, DocumentService>();
|
||||||
|
|
||||||
```python
|
// Use Options pattern for configuration
|
||||||
from typing import Protocol
|
builder.Services.Configure<AppSettings>(builder.Configuration.GetSection("App"));
|
||||||
|
|
||||||
class DocumentRepository(Protocol):
|
public class MyService(IOptions<AppSettings> options)
|
||||||
def find_all(self, filters: dict | None = None) -> list[Document]: ...
|
{
|
||||||
def find_by_id(self, id: str) -> Document | None: ...
|
private readonly AppSettings _settings = options.Value;
|
||||||
def create(self, data: dict) -> Document: ...
|
}
|
||||||
def update(self, id: str, data: dict) -> Document: ...
|
|
||||||
def delete(self, id: str) -> None: ...
|
// Avoid service locator pattern
|
||||||
|
// Bad: var service = serviceProvider.GetService<IMyService>();
|
||||||
|
// Good: Constructor injection
|
||||||
```
|
```
|
||||||
|
|
||||||
### Service Layer
|
## Entity Framework Core
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
class InferenceService:
|
// Always use AsNoTracking for read-only queries
|
||||||
def __init__(self, model_path: str, use_gpu: bool = True):
|
await _context.Documents.AsNoTracking().ToListAsync(ct);
|
||||||
self.pipeline = InferencePipeline(model_path=model_path, use_gpu=use_gpu)
|
|
||||||
|
|
||||||
async def process(self, file: UploadFile, confidence_threshold: float) -> InferenceResult:
|
// Use projection to select only needed fields
|
||||||
temp_path = self._save_temp_file(file)
|
await _context.Documents
|
||||||
try:
|
.Where(d => d.Status == "Active")
|
||||||
return self.pipeline.process_pdf(temp_path)
|
.Select(d => new DocumentDto(d.Id, d.Name))
|
||||||
finally:
|
.ToListAsync(ct);
|
||||||
temp_path.unlink(missing_ok=True)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Dependency Injection
|
// Prevent N+1 with Include or projection
|
||||||
|
await _context.Documents.Include(d => d.Labels).ToListAsync(ct);
|
||||||
|
|
||||||
```python
|
// Use explicit transactions for multiple operations
|
||||||
from functools import lru_cache
|
await using var tx = await _context.Database.BeginTransactionAsync(ct);
|
||||||
from pydantic_settings import BaseSettings
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
// Configure entities with IEntityTypeConfiguration
|
||||||
db_host: str = "localhost"
|
public class DocumentConfiguration : IEntityTypeConfiguration<Document>
|
||||||
db_password: str
|
{
|
||||||
model_path: str = "runs/train/invoice_fields/weights/best.pt"
|
public void Configure(EntityTypeBuilder<Document> builder)
|
||||||
class Config:
|
{
|
||||||
env_file = ".env"
|
builder.HasKey(d => d.Id);
|
||||||
|
builder.Property(d => d.Name).HasMaxLength(200).IsRequired();
|
||||||
@lru_cache()
|
builder.HasIndex(d => d.Status);
|
||||||
def get_settings() -> Settings:
|
}
|
||||||
return Settings()
|
}
|
||||||
|
|
||||||
def get_inference_service(settings: Settings = Depends(get_settings)) -> InferenceService:
|
|
||||||
return InferenceService(model_path=settings.model_path)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Database Patterns
|
|
||||||
|
|
||||||
### Connection Pooling
|
|
||||||
|
|
||||||
```python
|
|
||||||
from psycopg2 import pool
|
|
||||||
from contextlib import contextmanager
|
|
||||||
|
|
||||||
db_pool = pool.ThreadedConnectionPool(minconn=2, maxconn=10, **db_config)
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = db_pool.getconn()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
db_pool.putconn(conn)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Query Optimization
|
|
||||||
|
|
||||||
```python
|
|
||||||
# GOOD: Select only needed columns
|
|
||||||
cur.execute("""
|
|
||||||
SELECT id, status, fields->>'InvoiceNumber' as invoice_number
|
|
||||||
FROM documents WHERE status = %s
|
|
||||||
ORDER BY created_at DESC LIMIT %s
|
|
||||||
""", ('processed', 10))
|
|
||||||
|
|
||||||
# BAD: SELECT * FROM documents
|
|
||||||
```
|
|
||||||
|
|
||||||
### N+1 Prevention
|
|
||||||
|
|
||||||
```python
|
|
||||||
# BAD: N+1 queries
|
|
||||||
for doc in documents:
|
|
||||||
doc.labels = get_labels(doc.id) # N queries
|
|
||||||
|
|
||||||
# GOOD: Batch fetch with JOIN
|
|
||||||
cur.execute("""
|
|
||||||
SELECT d.id, d.status, array_agg(l.label) as labels
|
|
||||||
FROM documents d
|
|
||||||
LEFT JOIN document_labels l ON d.id = l.document_id
|
|
||||||
GROUP BY d.id, d.status
|
|
||||||
""")
|
|
||||||
```
|
|
||||||
|
|
||||||
### Transaction Pattern
|
|
||||||
|
|
||||||
```python
|
|
||||||
def create_document_with_labels(doc_data: dict, labels: list[dict]) -> str:
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
try:
|
|
||||||
with conn.cursor() as cur:
|
|
||||||
cur.execute("INSERT INTO documents ... RETURNING id", ...)
|
|
||||||
doc_id = cur.fetchone()[0]
|
|
||||||
for label in labels:
|
|
||||||
cur.execute("INSERT INTO document_labels ...", ...)
|
|
||||||
conn.commit()
|
|
||||||
return doc_id
|
|
||||||
except Exception:
|
|
||||||
conn.rollback()
|
|
||||||
raise
|
|
||||||
```
|
|
||||||
|
|
||||||
## Caching
|
|
||||||
|
|
||||||
```python
|
|
||||||
from cachetools import TTLCache
|
|
||||||
|
|
||||||
_cache = TTLCache(maxsize=1000, ttl=300)
|
|
||||||
|
|
||||||
def get_document_cached(doc_id: str) -> Document | None:
|
|
||||||
if doc_id in _cache:
|
|
||||||
return _cache[doc_id]
|
|
||||||
doc = repo.find_by_id(doc_id)
|
|
||||||
if doc:
|
|
||||||
_cache[doc_id] = doc
|
|
||||||
return doc
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Error Handling
|
## Error Handling
|
||||||
|
|
||||||
### Exception Hierarchy
|
```csharp
|
||||||
|
// Create domain-specific exceptions
|
||||||
|
public class NotFoundException(string resource, Guid id)
|
||||||
|
: Exception($"{resource} not found: {id}");
|
||||||
|
|
||||||
```python
|
// Use global exception handler
|
||||||
class AppError(Exception):
|
public class GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger) : IExceptionHandler
|
||||||
def __init__(self, message: str, status_code: int = 500):
|
{
|
||||||
self.message = message
|
public async ValueTask<bool> TryHandleAsync(HttpContext ctx, Exception ex, CancellationToken ct)
|
||||||
self.status_code = status_code
|
{
|
||||||
|
logger.LogError(ex, "Error: {Message}", ex.Message);
|
||||||
|
ctx.Response.StatusCode = ex is NotFoundException ? 404 : 500;
|
||||||
|
await ctx.Response.WriteAsJsonAsync(new { error = ex.Message }, ct);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class NotFoundError(AppError):
|
// Use Result pattern for expected failures
|
||||||
def __init__(self, resource: str, id: str):
|
public Result<Document> Validate(CreateRequest request) =>
|
||||||
super().__init__(f"{resource} not found: {id}", 404)
|
string.IsNullOrEmpty(request.Name)
|
||||||
|
? Result<Document>.Fail("Name is required")
|
||||||
class ValidationError(AppError):
|
: Result<Document>.Ok(new Document(request.Name));
|
||||||
def __init__(self, message: str):
|
|
||||||
super().__init__(message, 400)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### FastAPI Exception Handler
|
## Validation
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
@app.exception_handler(AppError)
|
// Use FluentValidation
|
||||||
async def app_error_handler(request: Request, exc: AppError):
|
public class CreateDocumentValidator : AbstractValidator<CreateDocumentRequest>
|
||||||
return JSONResponse(status_code=exc.status_code, content={"success": False, "error": exc.message})
|
{
|
||||||
|
public CreateDocumentValidator()
|
||||||
|
{
|
||||||
|
RuleFor(x => x.Name).NotEmpty().MaximumLength(200);
|
||||||
|
RuleFor(x => x.Type).Must(BeValidType).WithMessage("Invalid document type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@app.exception_handler(Exception)
|
// Or use Data Annotations for simple cases
|
||||||
async def generic_error_handler(request: Request, exc: Exception):
|
public record CreateRequest(
|
||||||
logger.error(f"Unexpected error: {exc}", exc_info=True)
|
[Required, MaxLength(200)] string Name,
|
||||||
return JSONResponse(status_code=500, content={"success": False, "error": "Internal server error"})
|
[Range(1, 100)] int Quantity);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Retry with Backoff
|
## Logging
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
async def retry_with_backoff(fn, max_retries: int = 3, base_delay: float = 1.0):
|
// Use structured logging with templates
|
||||||
last_error = None
|
logger.LogInformation("Processing document {DocumentId} for user {UserId}", docId, userId);
|
||||||
for attempt in range(max_retries):
|
|
||||||
try:
|
// Use appropriate log levels
|
||||||
return await fn() if asyncio.iscoroutinefunction(fn) else fn()
|
logger.LogDebug("Cache hit for key {Key}", key); // Development details
|
||||||
except Exception as e:
|
logger.LogInformation("Document {Id} created", id); // Normal operations
|
||||||
last_error = e
|
logger.LogWarning("Retry attempt {Attempt} for {Op}", n, op); // Potential issues
|
||||||
if attempt < max_retries - 1:
|
logger.LogError(ex, "Failed to process {DocumentId}", id); // Errors
|
||||||
await asyncio.sleep(base_delay * (2 ** attempt))
|
|
||||||
raise last_error
|
// Configure log filtering in appsettings
|
||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning",
|
||||||
|
"Microsoft.EntityFrameworkCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Rate Limiting
|
## API Design
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
from time import time
|
[ApiController]
|
||||||
from collections import defaultdict
|
[Route("api/v1/[controller]")]
|
||||||
|
public class DocumentsController(IDocumentService service) : ControllerBase
|
||||||
|
{
|
||||||
|
[HttpGet("{id:guid}")]
|
||||||
|
[ProducesResponseType<Document>(200)]
|
||||||
|
[ProducesResponseType(404)]
|
||||||
|
public async Task<IActionResult> Get(Guid id, CancellationToken ct)
|
||||||
|
{
|
||||||
|
var doc = await service.GetAsync(id, ct);
|
||||||
|
return doc is null ? NotFound() : Ok(doc);
|
||||||
|
}
|
||||||
|
|
||||||
class RateLimiter:
|
[HttpPost]
|
||||||
def __init__(self):
|
public async Task<IActionResult> Create(CreateRequest request, CancellationToken ct)
|
||||||
self.requests: dict[str, list[float]] = defaultdict(list)
|
{
|
||||||
|
var doc = await service.CreateAsync(request, ct);
|
||||||
def check_limit(self, identifier: str, max_requests: int, window_sec: int) -> bool:
|
return CreatedAtAction(nameof(Get), new { id = doc.Id }, doc);
|
||||||
now = time()
|
}
|
||||||
self.requests[identifier] = [t for t in self.requests[identifier] if now - t < window_sec]
|
}
|
||||||
if len(self.requests[identifier]) >= max_requests:
|
|
||||||
return False
|
|
||||||
self.requests[identifier].append(now)
|
|
||||||
return True
|
|
||||||
|
|
||||||
limiter = RateLimiter()
|
|
||||||
|
|
||||||
@app.middleware("http")
|
|
||||||
async def rate_limit_middleware(request: Request, call_next):
|
|
||||||
ip = request.client.host
|
|
||||||
if not limiter.check_limit(ip, max_requests=100, window_sec=60):
|
|
||||||
return JSONResponse(status_code=429, content={"error": "Rate limit exceeded"})
|
|
||||||
return await call_next(request)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Logging & Middleware
|
## Testing
|
||||||
|
|
||||||
### Request Logging
|
```csharp
|
||||||
|
// Use descriptive test names
|
||||||
|
[Fact]
|
||||||
|
public async Task GetById_WithValidId_ReturnsDocument()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var repo = Substitute.For<IRepository<Document>>();
|
||||||
|
repo.GetByIdAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>())
|
||||||
|
.Returns(new Document("Test"));
|
||||||
|
var service = new DocumentService(repo);
|
||||||
|
|
||||||
```python
|
// Act
|
||||||
@app.middleware("http")
|
var result = await service.GetAsync(Guid.NewGuid(), CancellationToken.None);
|
||||||
async def log_requests(request: Request, call_next):
|
|
||||||
request_id = str(uuid.uuid4())[:8]
|
// Assert
|
||||||
start_time = time.time()
|
result.Should().NotBeNull();
|
||||||
logger.info(f"[{request_id}] {request.method} {request.url.path}")
|
result!.Name.Should().Be("Test");
|
||||||
response = await call_next(request)
|
}
|
||||||
duration_ms = (time.time() - start_time) * 1000
|
|
||||||
logger.info(f"[{request_id}] Completed {response.status_code} in {duration_ms:.2f}ms")
|
// Use WebApplicationFactory for integration tests
|
||||||
return response
|
public class ApiTests(WebApplicationFactory<Program> factory) : IClassFixture<WebApplicationFactory<Program>>
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task GetDocuments_ReturnsSuccess()
|
||||||
|
{
|
||||||
|
var client = factory.CreateClient();
|
||||||
|
var response = await client.GetAsync("/api/v1/documents");
|
||||||
|
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Structured Logging
|
## Performance
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
class JSONFormatter(logging.Formatter):
|
// Use IMemoryCache for frequently accessed data
|
||||||
def format(self, record):
|
public class CachedService(IMemoryCache cache, IRepository<Document> repo)
|
||||||
return json.dumps({
|
{
|
||||||
"timestamp": datetime.utcnow().isoformat(),
|
public async Task<Document?> GetAsync(Guid id, CancellationToken ct) =>
|
||||||
"level": record.levelname,
|
await cache.GetOrCreateAsync($"doc:{id}", async entry =>
|
||||||
"message": record.getMessage(),
|
{
|
||||||
"module": record.module,
|
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5);
|
||||||
})
|
return await repo.GetByIdAsync(id, ct);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use pagination for large collections
|
||||||
|
public async Task<PagedResult<Document>> GetPagedAsync(int page, int size, CancellationToken ct) =>
|
||||||
|
new(
|
||||||
|
await _context.Documents.Skip((page - 1) * size).Take(size).ToListAsync(ct),
|
||||||
|
await _context.Documents.CountAsync(ct)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Use IAsyncEnumerable for streaming large datasets
|
||||||
|
public async IAsyncEnumerable<Document> StreamAllAsync([EnumeratorCancellation] CancellationToken ct)
|
||||||
|
{
|
||||||
|
await foreach (var doc in _context.Documents.AsAsyncEnumerable().WithCancellation(ct))
|
||||||
|
yield return doc;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Background Tasks
|
## Security
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
from fastapi import BackgroundTasks
|
// Never hardcode secrets
|
||||||
|
var apiKey = builder.Configuration["ApiKey"]; // From environment/secrets
|
||||||
|
|
||||||
def send_notification(document_id: str, status: str):
|
// Use parameterized queries (EF Core does this automatically)
|
||||||
logger.info(f"Notification: {document_id} -> {status}")
|
// Bad: $"SELECT * FROM Users WHERE Id = {id}"
|
||||||
|
// Good: _context.Users.Where(u => u.Id == id)
|
||||||
|
|
||||||
@router.post("/infer")
|
// Validate and sanitize all inputs
|
||||||
async def infer(file: UploadFile, background_tasks: BackgroundTasks):
|
// Use HTTPS in production
|
||||||
result = await process_document(file)
|
// Implement rate limiting
|
||||||
background_tasks.add_task(send_notification, result.document_id, "completed")
|
builder.Services.AddRateLimiter(options => { ... });
|
||||||
return result
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Key Principles
|
|
||||||
|
|
||||||
- Repository pattern: Abstract data access
|
|
||||||
- Service layer: Business logic separated from routes
|
|
||||||
- Dependency injection via `Depends()`
|
|
||||||
- Connection pooling for database
|
|
||||||
- Parameterized queries only (no f-strings in SQL)
|
|
||||||
- Batch fetch to prevent N+1
|
|
||||||
- Consistent `ApiResponse[T]` format
|
|
||||||
- Exception hierarchy with proper status codes
|
|
||||||
- Rate limit by IP
|
|
||||||
- Structured logging with request ID
|
|
||||||
@@ -1,665 +1,234 @@
|
|||||||
---
|
---
|
||||||
name: coding-standards
|
name: coding-standards
|
||||||
description: Universal coding standards, best practices, and patterns for Python, FastAPI, and data processing development.
|
description: .NET/C# coding standards and best practices.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Coding Standards & Best Practices
|
# .NET Coding Standards
|
||||||
|
|
||||||
Python coding standards for the Invoice Master project.
|
## Core Principles
|
||||||
|
|
||||||
## Code Quality Principles
|
- **Readability First** - Clear names, self-documenting code
|
||||||
|
- **KISS** - Simplest solution that works
|
||||||
|
- **DRY** - Extract common logic, avoid copy-paste
|
||||||
|
- **YAGNI** - Don't build features before needed
|
||||||
|
|
||||||
### 1. Readability First
|
## Naming Conventions
|
||||||
- Code is read more than written
|
|
||||||
- Clear variable and function names
|
|
||||||
- Self-documenting code preferred over comments
|
|
||||||
- Consistent formatting (follow PEP 8)
|
|
||||||
|
|
||||||
### 2. KISS (Keep It Simple, Stupid)
|
```csharp
|
||||||
- Simplest solution that works
|
// PascalCase: Types, methods, properties, public fields
|
||||||
- Avoid over-engineering
|
public class DocumentService { }
|
||||||
- No premature optimization
|
public async Task<Document> GetByIdAsync(Guid id) { }
|
||||||
- Easy to understand > clever code
|
public string InvoiceNumber { get; init; }
|
||||||
|
|
||||||
### 3. DRY (Don't Repeat Yourself)
|
// camelCase: Parameters, local variables, private fields with underscore
|
||||||
- Extract common logic into functions
|
private readonly ILogger<DocumentService> _logger;
|
||||||
- Create reusable utilities
|
public void Process(string documentId, int pageCount) { }
|
||||||
- Share modules across the codebase
|
|
||||||
- Avoid copy-paste programming
|
|
||||||
|
|
||||||
### 4. YAGNI (You Aren't Gonna Need It)
|
// Interfaces: I prefix
|
||||||
- Don't build features before they're needed
|
public interface IDocumentRepository { }
|
||||||
- Avoid speculative generality
|
|
||||||
- Add complexity only when required
|
|
||||||
- Start simple, refactor when needed
|
|
||||||
|
|
||||||
## Python Standards
|
// Async methods: Async suffix
|
||||||
|
public async Task<Document> LoadAsync(CancellationToken ct)
|
||||||
### Variable Naming
|
|
||||||
|
|
||||||
```python
|
|
||||||
# GOOD: Descriptive names
|
|
||||||
invoice_number = "INV-2024-001"
|
|
||||||
is_valid_document = True
|
|
||||||
total_confidence_score = 0.95
|
|
||||||
|
|
||||||
# BAD: Unclear names
|
|
||||||
inv = "INV-2024-001"
|
|
||||||
flag = True
|
|
||||||
x = 0.95
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Function Naming
|
## Modern C# Features
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
# GOOD: Verb-noun pattern with type hints
|
// Records for DTOs and value objects
|
||||||
def extract_invoice_fields(pdf_path: Path) -> dict[str, str]:
|
public sealed record CreateDocumentRequest(string Name, string Type);
|
||||||
"""Extract fields from invoice PDF."""
|
public sealed record DocumentDto(Guid Id, string Name, DateTime CreatedAt);
|
||||||
...
|
|
||||||
|
|
||||||
def calculate_confidence(predictions: list[float]) -> float:
|
// Primary constructors
|
||||||
"""Calculate average confidence score."""
|
public class DocumentService(IRepository<Document> repo, ILogger<DocumentService> logger)
|
||||||
...
|
{
|
||||||
|
public async Task<Document?> GetAsync(Guid id, CancellationToken ct) =>
|
||||||
|
await repo.GetByIdAsync(id, ct);
|
||||||
|
}
|
||||||
|
|
||||||
def is_valid_bankgiro(value: str) -> bool:
|
// Pattern matching
|
||||||
"""Check if value is valid Bankgiro number."""
|
var message = result switch
|
||||||
...
|
{
|
||||||
|
{ IsSuccess: true, Value: var doc } => $"Found: {doc.Name}",
|
||||||
|
{ Error: var err } => $"Error: {err}",
|
||||||
|
_ => "Unknown"
|
||||||
|
};
|
||||||
|
|
||||||
# BAD: Unclear or noun-only
|
// Collection expressions
|
||||||
def invoice(path):
|
int[] numbers = [1, 2, 3];
|
||||||
...
|
List<string> names = ["Alice", "Bob"];
|
||||||
|
|
||||||
def confidence(p):
|
// Null coalescing
|
||||||
...
|
var name = user?.Name ?? "Unknown";
|
||||||
|
list ??= [];
|
||||||
def bankgiro(v):
|
|
||||||
...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Type Hints (REQUIRED)
|
## Immutability (Critical)
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
# GOOD: Full type annotations
|
// GOOD: Create new objects
|
||||||
from typing import Optional
|
public record User(string Name, int Age)
|
||||||
from pathlib import Path
|
{
|
||||||
from dataclasses import dataclass
|
public User WithName(string newName) => this with { Name = newName };
|
||||||
|
}
|
||||||
|
|
||||||
@dataclass
|
// GOOD: Immutable collections
|
||||||
class InferenceResult:
|
public IReadOnlyList<string> GetNames() => _names.AsReadOnly();
|
||||||
document_id: str
|
|
||||||
fields: dict[str, str]
|
|
||||||
confidence: dict[str, float]
|
|
||||||
processing_time_ms: float
|
|
||||||
|
|
||||||
def process_document(
|
// BAD: Mutation
|
||||||
pdf_path: Path,
|
public void UpdateUser(User user, string name)
|
||||||
confidence_threshold: float = 0.5
|
{
|
||||||
) -> InferenceResult:
|
user.Name = name; // MUTATION!
|
||||||
"""Process PDF and return extracted fields."""
|
}
|
||||||
...
|
|
||||||
|
|
||||||
# BAD: No type hints
|
|
||||||
def process_document(pdf_path, confidence_threshold=0.5):
|
|
||||||
...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Immutability Pattern (CRITICAL)
|
## Error Handling
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
# GOOD: Create new objects, don't mutate
|
// Domain exceptions
|
||||||
def update_fields(fields: dict[str, str], updates: dict[str, str]) -> dict[str, str]:
|
public class NotFoundException(string resource, Guid id)
|
||||||
return {**fields, **updates}
|
: Exception($"{resource} not found: {id}");
|
||||||
|
|
||||||
def add_item(items: list[str], new_item: str) -> list[str]:
|
// Comprehensive handling
|
||||||
return [*items, new_item]
|
public async Task<Document> LoadAsync(Guid id, CancellationToken ct)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var doc = await _repo.GetByIdAsync(id, ct);
|
||||||
|
return doc ?? throw new NotFoundException("Document", id);
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (ex is not NotFoundException)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Failed to load document {Id}", id);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# BAD: Direct mutation
|
// Result pattern for expected failures
|
||||||
def update_fields(fields: dict[str, str], updates: dict[str, str]) -> dict[str, str]:
|
public Result<Document> Validate(CreateRequest request) =>
|
||||||
fields.update(updates) # MUTATION!
|
string.IsNullOrEmpty(request.Name)
|
||||||
return fields
|
? Result<Document>.Fail("Name required")
|
||||||
|
: Result<Document>.Ok(new Document(request.Name));
|
||||||
def add_item(items: list[str], new_item: str) -> list[str]:
|
|
||||||
items.append(new_item) # MUTATION!
|
|
||||||
return items
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Error Handling
|
## Async/Await
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
import logging
|
// Always pass CancellationToken
|
||||||
|
public async Task<Document> GetAsync(Guid id, CancellationToken ct)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
// Use ConfigureAwait(false) in libraries
|
||||||
|
await _client.GetAsync(url, ct).ConfigureAwait(false);
|
||||||
|
|
||||||
# GOOD: Comprehensive error handling with logging
|
// Avoid async void
|
||||||
def load_model(model_path: Path) -> Model:
|
public async Task ProcessAsync() { } // Good
|
||||||
"""Load YOLO model from path."""
|
public async void Process() { } // Bad
|
||||||
try:
|
|
||||||
if not model_path.exists():
|
|
||||||
raise FileNotFoundError(f"Model not found: {model_path}")
|
|
||||||
|
|
||||||
model = YOLO(str(model_path))
|
// Parallel when independent
|
||||||
logger.info(f"Model loaded: {model_path}")
|
var tasks = ids.Select(id => GetAsync(id, ct));
|
||||||
return model
|
var results = await Task.WhenAll(tasks);
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Failed to load model: {e}")
|
|
||||||
raise RuntimeError(f"Model loading failed: {model_path}") from e
|
|
||||||
|
|
||||||
# BAD: No error handling
|
|
||||||
def load_model(model_path):
|
|
||||||
return YOLO(str(model_path))
|
|
||||||
|
|
||||||
# BAD: Bare except
|
|
||||||
def load_model(model_path):
|
|
||||||
try:
|
|
||||||
return YOLO(str(model_path))
|
|
||||||
except: # Never use bare except!
|
|
||||||
return None
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Async Best Practices
|
## LINQ Best Practices
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
import asyncio
|
// Prefer method syntax for complex queries
|
||||||
|
var result = documents
|
||||||
|
.Where(d => d.Status == "Active")
|
||||||
|
.OrderByDescending(d => d.CreatedAt)
|
||||||
|
.Select(d => new DocumentDto(d.Id, d.Name, d.CreatedAt))
|
||||||
|
.Take(10);
|
||||||
|
|
||||||
# GOOD: Parallel execution when possible
|
// Use Any() instead of Count() > 0
|
||||||
async def process_batch(pdf_paths: list[Path]) -> list[InferenceResult]:
|
if (documents.Any(d => d.IsValid)) { }
|
||||||
tasks = [process_document(path) for path in pdf_paths]
|
|
||||||
results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
||||||
|
|
||||||
# Handle exceptions
|
// Avoid multiple enumerations
|
||||||
valid_results = []
|
var list = documents.ToList(); // Materialize once
|
||||||
for path, result in zip(pdf_paths, results):
|
var count = list.Count;
|
||||||
if isinstance(result, Exception):
|
var first = list.FirstOrDefault();
|
||||||
logger.error(f"Failed to process {path}: {result}")
|
|
||||||
else:
|
|
||||||
valid_results.append(result)
|
|
||||||
return valid_results
|
|
||||||
|
|
||||||
# BAD: Sequential when unnecessary
|
|
||||||
async def process_batch(pdf_paths: list[Path]) -> list[InferenceResult]:
|
|
||||||
results = []
|
|
||||||
for path in pdf_paths:
|
|
||||||
result = await process_document(path)
|
|
||||||
results.append(result)
|
|
||||||
return results
|
|
||||||
```
|
|
||||||
|
|
||||||
### Context Managers
|
|
||||||
|
|
||||||
```python
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from pathlib import Path
|
|
||||||
import tempfile
|
|
||||||
|
|
||||||
# GOOD: Proper resource management
|
|
||||||
@contextmanager
|
|
||||||
def temp_pdf_copy(pdf_path: Path):
|
|
||||||
"""Create temporary copy of PDF for processing."""
|
|
||||||
with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as tmp:
|
|
||||||
tmp.write(pdf_path.read_bytes())
|
|
||||||
tmp_path = Path(tmp.name)
|
|
||||||
try:
|
|
||||||
yield tmp_path
|
|
||||||
finally:
|
|
||||||
tmp_path.unlink(missing_ok=True)
|
|
||||||
|
|
||||||
# Usage
|
|
||||||
with temp_pdf_copy(original_pdf) as tmp_pdf:
|
|
||||||
result = process_pdf(tmp_pdf)
|
|
||||||
```
|
|
||||||
|
|
||||||
## FastAPI Best Practices
|
|
||||||
|
|
||||||
### Route Structure
|
|
||||||
|
|
||||||
```python
|
|
||||||
from fastapi import APIRouter, HTTPException, Depends, Query, File, UploadFile
|
|
||||||
from pydantic import BaseModel
|
|
||||||
|
|
||||||
router = APIRouter(prefix="/api/v1", tags=["inference"])
|
|
||||||
|
|
||||||
class InferenceResponse(BaseModel):
|
|
||||||
success: bool
|
|
||||||
document_id: str
|
|
||||||
fields: dict[str, str]
|
|
||||||
confidence: dict[str, float]
|
|
||||||
processing_time_ms: float
|
|
||||||
|
|
||||||
@router.post("/infer", response_model=InferenceResponse)
|
|
||||||
async def infer_document(
|
|
||||||
file: UploadFile = File(...),
|
|
||||||
confidence_threshold: float = Query(0.5, ge=0.0, le=1.0)
|
|
||||||
) -> InferenceResponse:
|
|
||||||
"""Process invoice PDF and extract fields."""
|
|
||||||
if not file.filename.endswith(".pdf"):
|
|
||||||
raise HTTPException(status_code=400, detail="Only PDF files accepted")
|
|
||||||
|
|
||||||
result = await inference_service.process(file, confidence_threshold)
|
|
||||||
return InferenceResponse(
|
|
||||||
success=True,
|
|
||||||
document_id=result.document_id,
|
|
||||||
fields=result.fields,
|
|
||||||
confidence=result.confidence,
|
|
||||||
processing_time_ms=result.processing_time_ms
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Input Validation with Pydantic
|
|
||||||
|
|
||||||
```python
|
|
||||||
from pydantic import BaseModel, Field, field_validator
|
|
||||||
from datetime import date
|
|
||||||
import re
|
|
||||||
|
|
||||||
class InvoiceData(BaseModel):
|
|
||||||
invoice_number: str = Field(..., min_length=1, max_length=50)
|
|
||||||
invoice_date: date
|
|
||||||
amount: float = Field(..., gt=0)
|
|
||||||
bankgiro: str | None = None
|
|
||||||
ocr_number: str | None = None
|
|
||||||
|
|
||||||
@field_validator("bankgiro")
|
|
||||||
@classmethod
|
|
||||||
def validate_bankgiro(cls, v: str | None) -> str | None:
|
|
||||||
if v is None:
|
|
||||||
return None
|
|
||||||
# Bankgiro: 7-8 digits
|
|
||||||
cleaned = re.sub(r"[^0-9]", "", v)
|
|
||||||
if not (7 <= len(cleaned) <= 8):
|
|
||||||
raise ValueError("Bankgiro must be 7-8 digits")
|
|
||||||
return cleaned
|
|
||||||
|
|
||||||
@field_validator("ocr_number")
|
|
||||||
@classmethod
|
|
||||||
def validate_ocr(cls, v: str | None) -> str | None:
|
|
||||||
if v is None:
|
|
||||||
return None
|
|
||||||
# OCR: 2-25 digits
|
|
||||||
cleaned = re.sub(r"[^0-9]", "", v)
|
|
||||||
if not (2 <= len(cleaned) <= 25):
|
|
||||||
raise ValueError("OCR must be 2-25 digits")
|
|
||||||
return cleaned
|
|
||||||
```
|
|
||||||
|
|
||||||
### Response Format
|
|
||||||
|
|
||||||
```python
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import Generic, TypeVar
|
|
||||||
|
|
||||||
T = TypeVar("T")
|
|
||||||
|
|
||||||
class ApiResponse(BaseModel, Generic[T]):
|
|
||||||
success: bool
|
|
||||||
data: T | None = None
|
|
||||||
error: str | None = None
|
|
||||||
meta: dict | None = None
|
|
||||||
|
|
||||||
# Success response
|
|
||||||
return ApiResponse(
|
|
||||||
success=True,
|
|
||||||
data=result,
|
|
||||||
meta={"processing_time_ms": elapsed_ms}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Error response
|
|
||||||
return ApiResponse(
|
|
||||||
success=False,
|
|
||||||
error="Invalid PDF format"
|
|
||||||
)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## File Organization
|
## File Organization
|
||||||
|
|
||||||
### Project Structure
|
|
||||||
|
|
||||||
```
|
```
|
||||||
src/
|
src/
|
||||||
├── cli/ # Command-line interfaces
|
Domain/ # Entities, value objects
|
||||||
│ ├── autolabel.py
|
Application/ # Use cases, DTOs, interfaces
|
||||||
│ ├── train.py
|
Infrastructure/ # EF Core, external services
|
||||||
│ └── infer.py
|
Api/ # Controllers, middleware
|
||||||
├── pdf/ # PDF processing
|
tests/
|
||||||
│ ├── extractor.py
|
Unit/
|
||||||
│ └── renderer.py
|
Integration/
|
||||||
├── ocr/ # OCR processing
|
|
||||||
│ ├── paddle_ocr.py
|
|
||||||
│ └── machine_code_parser.py
|
|
||||||
├── inference/ # Inference pipeline
|
|
||||||
│ ├── pipeline.py
|
|
||||||
│ ├── yolo_detector.py
|
|
||||||
│ └── field_extractor.py
|
|
||||||
├── normalize/ # Field normalization
|
|
||||||
│ ├── base.py
|
|
||||||
│ ├── date_normalizer.py
|
|
||||||
│ └── amount_normalizer.py
|
|
||||||
├── web/ # FastAPI application
|
|
||||||
│ ├── app.py
|
|
||||||
│ ├── routes.py
|
|
||||||
│ ├── services.py
|
|
||||||
│ └── schemas.py
|
|
||||||
└── utils/ # Shared utilities
|
|
||||||
├── validators.py
|
|
||||||
├── text_cleaner.py
|
|
||||||
└── logging.py
|
|
||||||
tests/ # Mirror of src structure
|
|
||||||
├── test_pdf/
|
|
||||||
├── test_ocr/
|
|
||||||
└── test_inference/
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### File Naming
|
**Guidelines:**
|
||||||
|
- Max 800 lines per file (typical 200-400)
|
||||||
|
- Max 50 lines per method
|
||||||
|
- One class per file (except nested)
|
||||||
|
- Group by feature, not by type
|
||||||
|
|
||||||
```
|
## Code Smells
|
||||||
src/ocr/paddle_ocr.py # snake_case for modules
|
|
||||||
src/inference/yolo_detector.py # snake_case for modules
|
```csharp
|
||||||
tests/test_paddle_ocr.py # test_ prefix for tests
|
// BAD: Deep nesting
|
||||||
config.py # snake_case for config
|
if (doc != null)
|
||||||
|
if (doc.IsValid)
|
||||||
|
if (doc.HasFields)
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// GOOD: Early returns
|
||||||
|
if (doc is null) return null;
|
||||||
|
if (!doc.IsValid) return null;
|
||||||
|
if (!doc.HasFields) return null;
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// BAD: Magic numbers
|
||||||
|
if (confidence > 0.5) { }
|
||||||
|
|
||||||
|
// GOOD: Named constants
|
||||||
|
private const double ConfidenceThreshold = 0.5;
|
||||||
|
if (confidence > ConfidenceThreshold) { }
|
||||||
```
|
```
|
||||||
|
|
||||||
### Module Size Guidelines
|
## Logging
|
||||||
|
|
||||||
- **Maximum**: 800 lines per file
|
```csharp
|
||||||
- **Typical**: 200-400 lines per file
|
// Structured logging with templates
|
||||||
- **Functions**: Max 50 lines each
|
_logger.LogInformation("Processing document {DocumentId}", docId);
|
||||||
- Extract utilities when modules grow too large
|
_logger.LogError(ex, "Failed to process {DocumentId}", docId);
|
||||||
|
|
||||||
## Comments & Documentation
|
// Appropriate levels
|
||||||
|
LogDebug // Development details
|
||||||
### When to Comment
|
LogInformation // Normal operations
|
||||||
|
LogWarning // Potential issues
|
||||||
```python
|
LogError // Errors with exceptions
|
||||||
# GOOD: Explain WHY, not WHAT
|
|
||||||
# Swedish Bankgiro uses Luhn algorithm with weight [1,2,1,2...]
|
|
||||||
def validate_bankgiro_checksum(bankgiro: str) -> bool:
|
|
||||||
...
|
|
||||||
|
|
||||||
# Payment line format: 7 groups separated by #, checksum at end
|
|
||||||
def parse_payment_line(line: str) -> PaymentLineData:
|
|
||||||
...
|
|
||||||
|
|
||||||
# BAD: Stating the obvious
|
|
||||||
# Increment counter by 1
|
|
||||||
count += 1
|
|
||||||
|
|
||||||
# Set name to user's name
|
|
||||||
name = user.name
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Docstrings for Public APIs
|
## Testing (AAA Pattern)
|
||||||
|
|
||||||
```python
|
```csharp
|
||||||
def extract_invoice_fields(
|
[Fact]
|
||||||
pdf_path: Path,
|
public async Task GetById_WithValidId_ReturnsDocument()
|
||||||
confidence_threshold: float = 0.5,
|
{
|
||||||
use_gpu: bool = True
|
// Arrange
|
||||||
) -> InferenceResult:
|
var repo = Substitute.For<IRepository<Document>>();
|
||||||
"""Extract structured fields from Swedish invoice PDF.
|
repo.GetByIdAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>())
|
||||||
|
.Returns(new Document("Test"));
|
||||||
|
var service = new DocumentService(repo);
|
||||||
|
|
||||||
Uses YOLOv11 for field detection and PaddleOCR for text extraction.
|
// Act
|
||||||
Applies field-specific normalization and validation.
|
var result = await service.GetAsync(Guid.NewGuid(), CancellationToken.None);
|
||||||
|
|
||||||
Args:
|
// Assert
|
||||||
pdf_path: Path to the invoice PDF file.
|
result.Should().NotBeNull();
|
||||||
confidence_threshold: Minimum confidence for field detection (0.0-1.0).
|
result!.Name.Should().Be("Test");
|
||||||
use_gpu: Whether to use GPU acceleration.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
InferenceResult containing extracted fields and confidence scores.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
FileNotFoundError: If PDF file doesn't exist.
|
|
||||||
ProcessingError: If OCR or detection fails.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
>>> result = extract_invoice_fields(Path("invoice.pdf"))
|
|
||||||
>>> print(result.fields["invoice_number"])
|
|
||||||
"INV-2024-001"
|
|
||||||
"""
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Performance Best Practices
|
|
||||||
|
|
||||||
### Caching
|
|
||||||
|
|
||||||
```python
|
|
||||||
from functools import lru_cache
|
|
||||||
from cachetools import TTLCache
|
|
||||||
|
|
||||||
# Static data: LRU cache
|
|
||||||
@lru_cache(maxsize=100)
|
|
||||||
def get_field_config(field_name: str) -> FieldConfig:
|
|
||||||
"""Load field configuration (cached)."""
|
|
||||||
return load_config(field_name)
|
|
||||||
|
|
||||||
# Dynamic data: TTL cache
|
|
||||||
_document_cache = TTLCache(maxsize=1000, ttl=300) # 5 minutes
|
|
||||||
|
|
||||||
def get_document_cached(doc_id: str) -> Document | None:
|
|
||||||
if doc_id in _document_cache:
|
|
||||||
return _document_cache[doc_id]
|
|
||||||
|
|
||||||
doc = repo.find_by_id(doc_id)
|
|
||||||
if doc:
|
|
||||||
_document_cache[doc_id] = doc
|
|
||||||
return doc
|
|
||||||
```
|
|
||||||
|
|
||||||
### Database Queries
|
|
||||||
|
|
||||||
```python
|
|
||||||
# GOOD: Select only needed columns
|
|
||||||
cur.execute("""
|
|
||||||
SELECT id, status, fields->>'invoice_number'
|
|
||||||
FROM documents
|
|
||||||
WHERE status = %s
|
|
||||||
LIMIT %s
|
|
||||||
""", ('processed', 10))
|
|
||||||
|
|
||||||
# BAD: Select everything
|
|
||||||
cur.execute("SELECT * FROM documents")
|
|
||||||
|
|
||||||
# GOOD: Batch operations
|
|
||||||
cur.executemany(
|
|
||||||
"INSERT INTO labels (doc_id, field, value) VALUES (%s, %s, %s)",
|
|
||||||
[(doc_id, f, v) for f, v in fields.items()]
|
|
||||||
)
|
|
||||||
|
|
||||||
# BAD: Individual inserts in loop
|
|
||||||
for field, value in fields.items():
|
|
||||||
cur.execute("INSERT INTO labels ...", (doc_id, field, value))
|
|
||||||
```
|
|
||||||
|
|
||||||
### Lazy Loading
|
|
||||||
|
|
||||||
```python
|
|
||||||
class InferencePipeline:
|
|
||||||
def __init__(self, model_path: Path):
|
|
||||||
self.model_path = model_path
|
|
||||||
self._model: YOLO | None = None
|
|
||||||
self._ocr: PaddleOCR | None = None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def model(self) -> YOLO:
|
|
||||||
"""Lazy load YOLO model."""
|
|
||||||
if self._model is None:
|
|
||||||
self._model = YOLO(str(self.model_path))
|
|
||||||
return self._model
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ocr(self) -> PaddleOCR:
|
|
||||||
"""Lazy load PaddleOCR."""
|
|
||||||
if self._ocr is None:
|
|
||||||
self._ocr = PaddleOCR(use_angle_cls=True, lang="latin")
|
|
||||||
return self._ocr
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing Standards
|
|
||||||
|
|
||||||
### Test Structure (AAA Pattern)
|
|
||||||
|
|
||||||
```python
|
|
||||||
def test_extract_bankgiro_valid():
|
|
||||||
# Arrange
|
|
||||||
text = "Bankgiro: 123-4567"
|
|
||||||
|
|
||||||
# Act
|
|
||||||
result = extract_bankgiro(text)
|
|
||||||
|
|
||||||
# Assert
|
|
||||||
assert result == "1234567"
|
|
||||||
|
|
||||||
def test_extract_bankgiro_invalid_returns_none():
|
|
||||||
# Arrange
|
|
||||||
text = "No bankgiro here"
|
|
||||||
|
|
||||||
# Act
|
|
||||||
result = extract_bankgiro(text)
|
|
||||||
|
|
||||||
# Assert
|
|
||||||
assert result is None
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test Naming
|
|
||||||
|
|
||||||
```python
|
|
||||||
# GOOD: Descriptive test names
|
|
||||||
def test_parse_payment_line_extracts_all_fields(): ...
|
|
||||||
def test_parse_payment_line_handles_missing_checksum(): ...
|
|
||||||
def test_validate_ocr_returns_false_for_invalid_checksum(): ...
|
|
||||||
|
|
||||||
# BAD: Vague test names
|
|
||||||
def test_parse(): ...
|
|
||||||
def test_works(): ...
|
|
||||||
def test_payment_line(): ...
|
|
||||||
```
|
|
||||||
|
|
||||||
### Fixtures
|
|
||||||
|
|
||||||
```python
|
|
||||||
import pytest
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def sample_invoice_pdf(tmp_path: Path) -> Path:
|
|
||||||
"""Create sample invoice PDF for testing."""
|
|
||||||
pdf_path = tmp_path / "invoice.pdf"
|
|
||||||
# Create test PDF...
|
|
||||||
return pdf_path
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def inference_pipeline(sample_model_path: Path) -> InferencePipeline:
|
|
||||||
"""Create inference pipeline with test model."""
|
|
||||||
return InferencePipeline(sample_model_path)
|
|
||||||
|
|
||||||
def test_process_invoice(inference_pipeline, sample_invoice_pdf):
|
|
||||||
result = inference_pipeline.process(sample_invoice_pdf)
|
|
||||||
assert result.fields.get("invoice_number") is not None
|
|
||||||
```
|
|
||||||
|
|
||||||
## Code Smell Detection
|
|
||||||
|
|
||||||
### 1. Long Functions
|
|
||||||
|
|
||||||
```python
|
|
||||||
# BAD: Function > 50 lines
|
|
||||||
def process_document():
|
|
||||||
# 100 lines of code...
|
|
||||||
|
|
||||||
# GOOD: Split into smaller functions
|
|
||||||
def process_document(pdf_path: Path) -> InferenceResult:
|
|
||||||
image = render_pdf(pdf_path)
|
|
||||||
detections = detect_fields(image)
|
|
||||||
ocr_results = extract_text(image, detections)
|
|
||||||
fields = normalize_fields(ocr_results)
|
|
||||||
return build_result(fields)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Deep Nesting
|
|
||||||
|
|
||||||
```python
|
|
||||||
# BAD: 5+ levels of nesting
|
|
||||||
if document:
|
|
||||||
if document.is_valid:
|
|
||||||
if document.has_fields:
|
|
||||||
if field in document.fields:
|
|
||||||
if document.fields[field]:
|
|
||||||
# Do something
|
|
||||||
|
|
||||||
# GOOD: Early returns
|
|
||||||
if not document:
|
|
||||||
return None
|
|
||||||
if not document.is_valid:
|
|
||||||
return None
|
|
||||||
if not document.has_fields:
|
|
||||||
return None
|
|
||||||
if field not in document.fields:
|
|
||||||
return None
|
|
||||||
if not document.fields[field]:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Do something
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Magic Numbers
|
|
||||||
|
|
||||||
```python
|
|
||||||
# BAD: Unexplained numbers
|
|
||||||
if confidence > 0.5:
|
|
||||||
...
|
|
||||||
time.sleep(3)
|
|
||||||
|
|
||||||
# GOOD: Named constants
|
|
||||||
CONFIDENCE_THRESHOLD = 0.5
|
|
||||||
RETRY_DELAY_SECONDS = 3
|
|
||||||
|
|
||||||
if confidence > CONFIDENCE_THRESHOLD:
|
|
||||||
...
|
|
||||||
time.sleep(RETRY_DELAY_SECONDS)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Mutable Default Arguments
|
|
||||||
|
|
||||||
```python
|
|
||||||
# BAD: Mutable default argument
|
|
||||||
def process_fields(fields: list = []): # DANGEROUS!
|
|
||||||
fields.append("new_field")
|
|
||||||
return fields
|
|
||||||
|
|
||||||
# GOOD: Use None as default
|
|
||||||
def process_fields(fields: list | None = None) -> list:
|
|
||||||
if fields is None:
|
|
||||||
fields = []
|
|
||||||
return [*fields, "new_field"]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Logging Standards
|
|
||||||
|
|
||||||
```python
|
|
||||||
import logging
|
|
||||||
|
|
||||||
# Module-level logger
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
# GOOD: Appropriate log levels
|
|
||||||
logger.debug("Processing document: %s", doc_id)
|
|
||||||
logger.info("Document processed successfully: %s", doc_id)
|
|
||||||
logger.warning("Low confidence score: %.2f", confidence)
|
|
||||||
logger.error("Failed to process document: %s", error)
|
|
||||||
|
|
||||||
# GOOD: Structured logging with extra data
|
|
||||||
logger.info(
|
|
||||||
"Inference complete",
|
|
||||||
extra={
|
|
||||||
"document_id": doc_id,
|
|
||||||
"field_count": len(fields),
|
|
||||||
"processing_time_ms": elapsed_ms
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
# BAD: Using print()
|
|
||||||
print(f"Processing {doc_id}") # Never in production!
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Remember**: Code quality is not negotiable. Clear, maintainable Python code with proper type hints enables confident development and refactoring.
|
## Key Rules
|
||||||
|
|
||||||
|
- Always use `CancellationToken` for async methods
|
||||||
|
- Prefer `records` for DTOs and immutable data
|
||||||
|
- Use `IReadOnlyList<T>` for return types
|
||||||
|
- Never use `async void` (except event handlers)
|
||||||
|
- Always handle `null` with pattern matching or null operators
|
||||||
|
- Use structured logging, never `Console.WriteLine`
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)CodeAnalysis.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)CodeAnalysis.ruleset</CodeAnalysisRuleSet>
|
||||||
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
||||||
<LangVersion>12.0</LangVersion>
|
<LangVersion>14.0</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -4,21 +4,21 @@ VisualStudioVersion = 17.0.31903.59
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8A4623CB-AB3F-4A20-8A6E-3A33B65D6F5A}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8A4623CB-AB3F-4A20-8A6E-3A33B65D6F5A}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvoiceMaster.API", "src\InvoiceMaster.API\InvoiceMaster.API.csproj", "{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FiscalFlow.Api", "src\FiscalFlow.Api\FiscalFlow.Api.csproj", "{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvoiceMaster.Core", "src\InvoiceMaster.Core\InvoiceMaster.Core.csproj", "{B2C3D4E5-F6A7-8901-BCDE-F23456789012}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FiscalFlow.Core", "src\FiscalFlow.Core\FiscalFlow.Core.csproj", "{B2C3D4E5-F6A7-8901-BCDE-F23456789012}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvoiceMaster.Application", "src\InvoiceMaster.Application\InvoiceMaster.Application.csproj", "{C3D4E5F6-A7B8-9012-CDEF-345678901234}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FiscalFlow.Application", "src\FiscalFlow.Application\FiscalFlow.Application.csproj", "{C3D4E5F6-A7B8-9012-CDEF-345678901234}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvoiceMaster.Infrastructure", "src\InvoiceMaster.Infrastructure\InvoiceMaster.Infrastructure.csproj", "{D4E5F6A7-B8C9-0123-DEFA-456789012345}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FiscalFlow.Infrastructure", "src\FiscalFlow.Infrastructure\FiscalFlow.Infrastructure.csproj", "{D4E5F6A7-B8C9-0123-DEFA-456789012345}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvoiceMaster.Integrations", "src\InvoiceMaster.Integrations\InvoiceMaster.Integrations.csproj", "{E5F6A7B8-C9D0-1234-EFAB-567890123456}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FiscalFlow.Integrations", "src\FiscalFlow.Integrations\FiscalFlow.Integrations.csproj", "{E5F6A7B8-C9D0-1234-EFAB-567890123456}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{F6A7B8C9-D0E1-2345-FABC-678901234567}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{F6A7B8C9-D0E1-2345-FABC-678901234567}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvoiceMaster.UnitTests", "tests\InvoiceMaster.UnitTests\InvoiceMaster.UnitTests.csproj", "{A7B8C9D0-E1F2-3456-ABCD-789012345678}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FiscalFlow.UnitTests", "tests\FiscalFlow.UnitTests\FiscalFlow.UnitTests.csproj", "{A7B8C9D0-E1F2-3456-ABCD-789012345678}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvoiceMaster.IntegrationTests", "tests\InvoiceMaster.IntegrationTests\InvoiceMaster.IntegrationTests.csproj", "{B8C9D0E1-F2A3-4567-BCDE-890123456789}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FiscalFlow.IntegrationTests", "tests\FiscalFlow.IntegrationTests\FiscalFlow.IntegrationTests.csproj", "{B8C9D0E1-F2A3-4567-BCDE-890123456789}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"sdk": {
|
"sdk": {
|
||||||
"version": "8.0.100",
|
"version": "10.0.100",
|
||||||
"rollForward": "latestFeature"
|
"rollForward": "latestFeature"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
using InvoiceMaster.Application.DTOs;
|
using FiscalFlow.Application.DTOs;
|
||||||
using InvoiceMaster.Core.Entities;
|
using FiscalFlow.Core.Entities;
|
||||||
using InvoiceMaster.Core.Interfaces;
|
using FiscalFlow.Core.Interfaces;
|
||||||
using InvoiceMaster.Integrations.Accounting;
|
using FiscalFlow.Integrations.Accounting;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace InvoiceMaster.API.Controllers;
|
namespace FiscalFlow.API.Controllers;
|
||||||
|
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/v1/accounting")]
|
[Route("api/v1/accounting")]
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
using InvoiceMaster.Application.Commands.Auth;
|
using FiscalFlow.Application.Commands.Auth;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace InvoiceMaster.API.Controllers;
|
namespace FiscalFlow.API.Controllers;
|
||||||
|
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/v1/auth")]
|
[Route("api/v1/auth")]
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace InvoiceMaster.API.Controllers;
|
namespace FiscalFlow.API.Controllers;
|
||||||
|
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/v1/health")]
|
[Route("api/v1/health")]
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
using InvoiceMaster.Application.Commands.Invoices;
|
using FiscalFlow.Application.Commands.Invoices;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
|
||||||
namespace InvoiceMaster.API.Controllers;
|
namespace FiscalFlow.API.Controllers;
|
||||||
|
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/v1/invoices")]
|
[Route("api/v1/invoices")]
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
using InvoiceMaster.Application.Commands.Invoices;
|
using FiscalFlow.Application.Commands.Invoices;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
|
||||||
namespace InvoiceMaster.API.Controllers;
|
namespace FiscalFlow.API.Controllers;
|
||||||
|
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/v1/invoices")]
|
[Route("api/v1/invoices")]
|
||||||
@@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace InvoiceMaster.API.Extensions;
|
namespace FiscalFlow.API.Extensions;
|
||||||
|
|
||||||
public static class AuthenticationExtensions
|
public static class AuthenticationExtensions
|
||||||
{
|
{
|
||||||
21
backend/src/FiscalFlow.Api/FiscalFlow.Api.csproj
Normal file
21
backend/src/FiscalFlow.Api/FiscalFlow.Api.csproj
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<AssemblyName>FiscalFlow.Api</AssemblyName>
|
||||||
|
<RootNamespace>FiscalFlow.Api</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.2.0" />
|
||||||
|
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||||
|
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\FiscalFlow.Application\FiscalFlow.Application.csproj" />
|
||||||
|
<ProjectReference Include="..\FiscalFlow.Infrastructure\FiscalFlow.Infrastructure.csproj" />
|
||||||
|
<ProjectReference Include="..\FiscalFlow.Integrations\FiscalFlow.Integrations.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
namespace InvoiceMaster.API.Middleware;
|
namespace FiscalFlow.API.Middleware;
|
||||||
|
|
||||||
public class ExceptionHandlingMiddleware
|
public class ExceptionHandlingMiddleware
|
||||||
{
|
{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using InvoiceMaster.API.Extensions;
|
using FiscalFlow.API.Extensions;
|
||||||
using InvoiceMaster.Application;
|
using FiscalFlow.Application;
|
||||||
using InvoiceMaster.Infrastructure.Data;
|
using FiscalFlow.Infrastructure.Data;
|
||||||
using InvoiceMaster.Infrastructure.Extensions;
|
using FiscalFlow.Infrastructure.Extensions;
|
||||||
using InvoiceMaster.Integrations.Extensions;
|
using FiscalFlow.Integrations.Extensions;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
[assembly: System.Reflection.AssemblyCompanyAttribute("FiscalFlow.Api")]
|
||||||
|
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||||
|
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||||
|
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+05ea67144f6a97e372ca4293ce2393e15a3f6bb7")]
|
||||||
|
[assembly: System.Reflection.AssemblyProductAttribute("FiscalFlow.Api")]
|
||||||
|
[assembly: System.Reflection.AssemblyTitleAttribute("FiscalFlow.Api")]
|
||||||
|
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||||
|
|
||||||
|
// Generated by the MSBuild WriteCodeFragment class.
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
8fc2a27aad0a8b77d5436cb35f33e0e94aa2ecbe90e0e1527cf1ba0b1d6dcff5
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
is_global = true
|
||||||
|
build_property.TargetFramework = net8.0
|
||||||
|
build_property.TargetFrameworkIdentifier = .NETCoreApp
|
||||||
|
build_property.TargetFrameworkVersion = v8.0
|
||||||
|
build_property.TargetPlatformMinVersion =
|
||||||
|
build_property.UsingMicrosoftNETSdkWeb = true
|
||||||
|
build_property.ProjectTypeGuids =
|
||||||
|
build_property.InvariantGlobalization =
|
||||||
|
build_property.PlatformNeutralAssembly =
|
||||||
|
build_property.EnforceExtendedAnalyzerRules =
|
||||||
|
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||||
|
build_property.RootNamespace = FiscalFlow.Api
|
||||||
|
build_property.RootNamespace = FiscalFlow.Api
|
||||||
|
build_property.ProjectDir = C:\Users\yaoji\git\ColaCoder\accounting-system\backend\src\InvoiceMaster.API\
|
||||||
|
build_property.EnableComHosting =
|
||||||
|
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||||
|
build_property.RazorLangVersion = 8.0
|
||||||
|
build_property.SupportLocalizedComponentNames =
|
||||||
|
build_property.GenerateRazorMetadataSourceChecksumAttributes =
|
||||||
|
build_property.MSBuildProjectDirectory = C:\Users\yaoji\git\ColaCoder\accounting-system\backend\src\InvoiceMaster.API
|
||||||
|
build_property._RazorSourceGeneratorDebug =
|
||||||
|
build_property.EffectiveAnalysisLevelStyle = 8.0
|
||||||
|
build_property.EnableCodeStyleSeverity =
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// <auto-generated/>
|
||||||
|
global using Microsoft.AspNetCore.Builder;
|
||||||
|
global using Microsoft.AspNetCore.Hosting;
|
||||||
|
global using Microsoft.AspNetCore.Http;
|
||||||
|
global using Microsoft.AspNetCore.Routing;
|
||||||
|
global using Microsoft.Extensions.Configuration;
|
||||||
|
global using Microsoft.Extensions.DependencyInjection;
|
||||||
|
global using Microsoft.Extensions.Hosting;
|
||||||
|
global using Microsoft.Extensions.Logging;
|
||||||
|
global using System;
|
||||||
|
global using System.Collections.Generic;
|
||||||
|
global using System.IO;
|
||||||
|
global using System.Linq;
|
||||||
|
global using System.Net.Http;
|
||||||
|
global using System.Net.Http.Json;
|
||||||
|
global using System.Threading;
|
||||||
|
global using System.Threading.Tasks;
|
||||||
@@ -0,0 +1,490 @@
|
|||||||
|
{
|
||||||
|
"format": 1,
|
||||||
|
"restore": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj": {}
|
||||||
|
},
|
||||||
|
"projects": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"projectName": "InvoiceMaster.API",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"packagesPath": "C:\\Users\\yaoji\\.nuget\\packages\\",
|
||||||
|
"outputPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\obj\\",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"fallbackFolders": [
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||||
|
],
|
||||||
|
"configFilePaths": [
|
||||||
|
"C:\\Users\\yaoji\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net8.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||||
|
"https://api.nuget.org/v3/index.json": {},
|
||||||
|
"https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"projectReferences": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj": {
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj"
|
||||||
|
},
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj": {
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj"
|
||||||
|
},
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Integrations\\InvoiceMaster.Integrations.csproj": {
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Integrations\\InvoiceMaster.Integrations.csproj"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"allWarningsAsErrors": true,
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restoreAuditProperties": {
|
||||||
|
"enableAudit": "true",
|
||||||
|
"auditLevel": "low",
|
||||||
|
"auditMode": "direct"
|
||||||
|
},
|
||||||
|
"SdkAnalysisLevel": "10.0.100"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"dependencies": {
|
||||||
|
"Serilog.AspNetCore": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"Serilog.Sinks.Console": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[5.0.1, )"
|
||||||
|
},
|
||||||
|
"Serilog.Sinks.File": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[5.0.0, )"
|
||||||
|
},
|
||||||
|
"StyleCop.Analyzers": {
|
||||||
|
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
|
||||||
|
"suppressParent": "All",
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[1.2.0-beta.556, )"
|
||||||
|
},
|
||||||
|
"Swashbuckle.AspNetCore": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[6.5.0, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48",
|
||||||
|
"net481"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.AspNetCore.App": {
|
||||||
|
"privateAssets": "none"
|
||||||
|
},
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.102/PortableRuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"projectName": "InvoiceMaster.Application",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"packagesPath": "C:\\Users\\yaoji\\.nuget\\packages\\",
|
||||||
|
"outputPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\obj\\",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"fallbackFolders": [
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||||
|
],
|
||||||
|
"configFilePaths": [
|
||||||
|
"C:\\Users\\yaoji\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net8.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||||
|
"https://api.nuget.org/v3/index.json": {},
|
||||||
|
"https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"projectReferences": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj": {
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"allWarningsAsErrors": true,
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restoreAuditProperties": {
|
||||||
|
"enableAudit": "true",
|
||||||
|
"auditLevel": "low",
|
||||||
|
"auditMode": "direct"
|
||||||
|
},
|
||||||
|
"SdkAnalysisLevel": "10.0.100"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"dependencies": {
|
||||||
|
"AutoMapper": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[12.0.1, )"
|
||||||
|
},
|
||||||
|
"FluentValidation": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[11.8.1, )"
|
||||||
|
},
|
||||||
|
"MediatR": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[12.2.0, )"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"StyleCop.Analyzers": {
|
||||||
|
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
|
||||||
|
"suppressParent": "All",
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[1.2.0-beta.556, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48",
|
||||||
|
"net481"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.102/PortableRuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"projectName": "InvoiceMaster.Core",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"packagesPath": "C:\\Users\\yaoji\\.nuget\\packages\\",
|
||||||
|
"outputPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\obj\\",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"fallbackFolders": [
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||||
|
],
|
||||||
|
"configFilePaths": [
|
||||||
|
"C:\\Users\\yaoji\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net8.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||||
|
"https://api.nuget.org/v3/index.json": {},
|
||||||
|
"https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"projectReferences": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"allWarningsAsErrors": true,
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restoreAuditProperties": {
|
||||||
|
"enableAudit": "true",
|
||||||
|
"auditLevel": "low",
|
||||||
|
"auditMode": "direct"
|
||||||
|
},
|
||||||
|
"SdkAnalysisLevel": "10.0.100"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"dependencies": {
|
||||||
|
"StyleCop.Analyzers": {
|
||||||
|
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
|
||||||
|
"suppressParent": "All",
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[1.2.0-beta.556, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48",
|
||||||
|
"net481"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.102/PortableRuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"projectName": "InvoiceMaster.Infrastructure",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"packagesPath": "C:\\Users\\yaoji\\.nuget\\packages\\",
|
||||||
|
"outputPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\obj\\",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"fallbackFolders": [
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||||
|
],
|
||||||
|
"configFilePaths": [
|
||||||
|
"C:\\Users\\yaoji\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net8.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||||
|
"https://api.nuget.org/v3/index.json": {},
|
||||||
|
"https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"projectReferences": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj": {
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"allWarningsAsErrors": true,
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restoreAuditProperties": {
|
||||||
|
"enableAudit": "true",
|
||||||
|
"auditLevel": "low",
|
||||||
|
"auditMode": "direct"
|
||||||
|
},
|
||||||
|
"SdkAnalysisLevel": "10.0.100"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"dependencies": {
|
||||||
|
"Azure.Storage.Blobs": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[12.19.1, )"
|
||||||
|
},
|
||||||
|
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"Microsoft.EntityFrameworkCore": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"Microsoft.EntityFrameworkCore.Tools": {
|
||||||
|
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
|
||||||
|
"suppressParent": "All",
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Http": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"Npgsql.EntityFrameworkCore.PostgreSQL": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"Polly": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.2.0, )"
|
||||||
|
},
|
||||||
|
"Polly.Extensions.Http": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[3.0.0, )"
|
||||||
|
},
|
||||||
|
"StyleCop.Analyzers": {
|
||||||
|
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
|
||||||
|
"suppressParent": "All",
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[1.2.0-beta.556, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48",
|
||||||
|
"net481"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.102/PortableRuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Integrations\\InvoiceMaster.Integrations.csproj": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Integrations\\InvoiceMaster.Integrations.csproj",
|
||||||
|
"projectName": "InvoiceMaster.Integrations",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Integrations\\InvoiceMaster.Integrations.csproj",
|
||||||
|
"packagesPath": "C:\\Users\\yaoji\\.nuget\\packages\\",
|
||||||
|
"outputPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Integrations\\obj\\",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"fallbackFolders": [
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||||
|
],
|
||||||
|
"configFilePaths": [
|
||||||
|
"C:\\Users\\yaoji\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net8.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||||
|
"https://api.nuget.org/v3/index.json": {},
|
||||||
|
"https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"projectReferences": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj": {
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"allWarningsAsErrors": true,
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restoreAuditProperties": {
|
||||||
|
"enableAudit": "true",
|
||||||
|
"auditLevel": "low",
|
||||||
|
"auditMode": "direct"
|
||||||
|
},
|
||||||
|
"SdkAnalysisLevel": "10.0.100"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Http": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Logging.Abstractions": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"StyleCop.Analyzers": {
|
||||||
|
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
|
||||||
|
"suppressParent": "All",
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[1.2.0-beta.556, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48",
|
||||||
|
"net481"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.102/PortableRuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||||
|
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||||
|
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||||
|
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||||
|
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\yaoji\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
|
||||||
|
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||||
|
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<SourceRoot Include="C:\Users\yaoji\.nuget\packages\" />
|
||||||
|
<SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<Import Project="$(NuGetPackageRoot)microsoft.extensions.apidescription.server\6.0.5\build\Microsoft.Extensions.ApiDescription.Server.props" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.apidescription.server\6.0.5\build\Microsoft.Extensions.ApiDescription.Server.props')" />
|
||||||
|
<Import Project="$(NuGetPackageRoot)swashbuckle.aspnetcore\6.5.0\build\Swashbuckle.AspNetCore.props" Condition="Exists('$(NuGetPackageRoot)swashbuckle.aspnetcore\6.5.0\build\Swashbuckle.AspNetCore.props')" />
|
||||||
|
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore\8.0.0\buildTransitive\net8.0\Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore\8.0.0\buildTransitive\net8.0\Microsoft.EntityFrameworkCore.props')" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<PkgMicrosoft_Extensions_ApiDescription_Server Condition=" '$(PkgMicrosoft_Extensions_ApiDescription_Server)' == '' ">C:\Users\yaoji\.nuget\packages\microsoft.extensions.apidescription.server\6.0.5</PkgMicrosoft_Extensions_ApiDescription_Server>
|
||||||
|
<PkgStyleCop_Analyzers_Unstable Condition=" '$(PkgStyleCop_Analyzers_Unstable)' == '' ">C:\Users\yaoji\.nuget\packages\stylecop.analyzers.unstable\1.2.0.556</PkgStyleCop_Analyzers_Unstable>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<Import Project="$(NuGetPackageRoot)system.text.json\8.0.0\buildTransitive\net6.0\System.Text.Json.targets" Condition="Exists('$(NuGetPackageRoot)system.text.json\8.0.0\buildTransitive\net6.0\System.Text.Json.targets')" />
|
||||||
|
<Import Project="$(NuGetPackageRoot)microsoft.extensions.apidescription.server\6.0.5\build\Microsoft.Extensions.ApiDescription.Server.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.apidescription.server\6.0.5\build\Microsoft.Extensions.ApiDescription.Server.targets')" />
|
||||||
|
<Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.binder\8.0.0\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.binder\8.0.0\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets')" />
|
||||||
|
<Import Project="$(NuGetPackageRoot)microsoft.extensions.options\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Options.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.options\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Options.targets')" />
|
||||||
|
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
3351
backend/src/FiscalFlow.Api/obj/project.assets.json
Normal file
3351
backend/src/FiscalFlow.Api/obj/project.assets.json
Normal file
File diff suppressed because it is too large
Load Diff
235
backend/src/FiscalFlow.Api/obj/project.nuget.cache
Normal file
235
backend/src/FiscalFlow.Api/obj/project.nuget.cache
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"dgSpecHash": "+5p9vl5fRd0=",
|
||||||
|
"success": false,
|
||||||
|
"projectFilePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"expectedPackageFiles": [
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\automapper\\12.0.1\\automapper.12.0.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\azure.core\\1.36.0\\azure.core.1.36.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\azure.storage.blobs\\12.19.1\\azure.storage.blobs.12.19.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\azure.storage.common\\12.18.1\\azure.storage.common.12.18.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\fluentvalidation\\11.8.1\\fluentvalidation.11.8.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\mediatr\\12.2.0\\mediatr.12.2.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\mediatr.contracts\\2.0.1\\mediatr.contracts.2.0.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.aspnetcore.cryptography.internal\\8.0.0\\microsoft.aspnetcore.cryptography.internal.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.aspnetcore.cryptography.keyderivation\\8.0.0\\microsoft.aspnetcore.cryptography.keyderivation.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.aspnetcore.identity.entityframeworkcore\\8.0.0\\microsoft.aspnetcore.identity.entityframeworkcore.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.bcl.asyncinterfaces\\1.1.1\\microsoft.bcl.asyncinterfaces.1.1.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.csharp\\4.7.0\\microsoft.csharp.4.7.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.entityframeworkcore\\8.0.0\\microsoft.entityframeworkcore.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.entityframeworkcore.abstractions\\8.0.0\\microsoft.entityframeworkcore.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.entityframeworkcore.analyzers\\8.0.0\\microsoft.entityframeworkcore.analyzers.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.entityframeworkcore.relational\\8.0.0\\microsoft.entityframeworkcore.relational.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.apidescription.server\\6.0.5\\microsoft.extensions.apidescription.server.6.0.5.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.caching.abstractions\\8.0.0\\microsoft.extensions.caching.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.caching.memory\\8.0.0\\microsoft.extensions.caching.memory.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.configuration\\8.0.0\\microsoft.extensions.configuration.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.configuration.abstractions\\8.0.0\\microsoft.extensions.configuration.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.configuration.binder\\8.0.0\\microsoft.extensions.configuration.binder.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.dependencyinjection\\8.0.0\\microsoft.extensions.dependencyinjection.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.dependencyinjection.abstractions\\8.0.0\\microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.dependencymodel\\8.0.0\\microsoft.extensions.dependencymodel.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.diagnostics\\8.0.0\\microsoft.extensions.diagnostics.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.diagnostics.abstractions\\8.0.0\\microsoft.extensions.diagnostics.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.fileproviders.abstractions\\8.0.0\\microsoft.extensions.fileproviders.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.hosting.abstractions\\8.0.0\\microsoft.extensions.hosting.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.http\\8.0.0\\microsoft.extensions.http.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.identity.core\\8.0.0\\microsoft.extensions.identity.core.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.identity.stores\\8.0.0\\microsoft.extensions.identity.stores.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.logging\\8.0.0\\microsoft.extensions.logging.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.logging.abstractions\\8.0.0\\microsoft.extensions.logging.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.options\\8.0.0\\microsoft.extensions.options.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.options.configurationextensions\\8.0.0\\microsoft.extensions.options.configurationextensions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.primitives\\8.0.0\\microsoft.extensions.primitives.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.openapi\\1.2.3\\microsoft.openapi.1.2.3.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\npgsql\\8.0.0\\npgsql.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\npgsql.entityframeworkcore.postgresql\\8.0.0\\npgsql.entityframeworkcore.postgresql.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\polly\\8.2.0\\polly.8.2.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\polly.core\\8.2.0\\polly.core.8.2.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\polly.extensions.http\\3.0.0\\polly.extensions.http.3.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\serilog\\3.1.1\\serilog.3.1.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\serilog.aspnetcore\\8.0.0\\serilog.aspnetcore.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\serilog.extensions.hosting\\8.0.0\\serilog.extensions.hosting.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\serilog.extensions.logging\\8.0.0\\serilog.extensions.logging.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\serilog.formatting.compact\\2.0.0\\serilog.formatting.compact.2.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\serilog.settings.configuration\\8.0.0\\serilog.settings.configuration.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\serilog.sinks.console\\5.0.1\\serilog.sinks.console.5.0.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\serilog.sinks.debug\\2.0.0\\serilog.sinks.debug.2.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\serilog.sinks.file\\5.0.0\\serilog.sinks.file.5.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\stylecop.analyzers\\1.2.0-beta.556\\stylecop.analyzers.1.2.0-beta.556.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\stylecop.analyzers.unstable\\1.2.0.556\\stylecop.analyzers.unstable.1.2.0.556.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\swashbuckle.aspnetcore\\6.5.0\\swashbuckle.aspnetcore.6.5.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\swashbuckle.aspnetcore.swagger\\6.5.0\\swashbuckle.aspnetcore.swagger.6.5.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\swashbuckle.aspnetcore.swaggergen\\6.5.0\\swashbuckle.aspnetcore.swaggergen.6.5.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\swashbuckle.aspnetcore.swaggerui\\6.5.0\\swashbuckle.aspnetcore.swaggerui.6.5.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.diagnostics.diagnosticsource\\8.0.0\\system.diagnostics.diagnosticsource.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.io.hashing\\6.0.0\\system.io.hashing.6.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.memory.data\\1.0.2\\system.memory.data.1.0.2.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.numerics.vectors\\4.5.0\\system.numerics.vectors.4.5.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.text.encodings.web\\8.0.0\\system.text.encodings.web.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.text.json\\8.0.0\\system.text.json.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.threading.tasks.extensions\\4.5.4\\system.threading.tasks.extensions.4.5.4.nupkg.sha512"
|
||||||
|
],
|
||||||
|
"logs": [
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1900",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Warning As Error: Error occurred while getting package vulnerability data: Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.API\\InvoiceMaster.API.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using InvoiceMaster.Application.Commands.Auth;
|
using FiscalFlow.Application.Commands.Auth;
|
||||||
using InvoiceMaster.Application.Services;
|
using FiscalFlow.Application.Services;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
|
|
||||||
namespace InvoiceMaster.Application.Commands.Auth.Handlers;
|
namespace FiscalFlow.Application.Commands.Auth.Handlers;
|
||||||
|
|
||||||
public class RegisterCommandHandler : IRequestHandler<RegisterCommand, AuthResultDto>
|
public class RegisterCommandHandler : IRequestHandler<RegisterCommand, AuthResultDto>
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using MediatR;
|
using MediatR;
|
||||||
|
|
||||||
namespace InvoiceMaster.Application.Commands.Auth;
|
namespace FiscalFlow.Application.Commands.Auth;
|
||||||
|
|
||||||
public record RegisterCommand(
|
public record RegisterCommand(
|
||||||
string Email,
|
string Email,
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
|
|
||||||
namespace InvoiceMaster.Application.Commands.Auth;
|
namespace FiscalFlow.Application.Commands.Auth;
|
||||||
|
|
||||||
public class RegisterCommandValidator : AbstractValidator<RegisterCommand>
|
public class RegisterCommandValidator : AbstractValidator<RegisterCommand>
|
||||||
{
|
{
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
using InvoiceMaster.Application.DTOs;
|
using FiscalFlow.Application.DTOs;
|
||||||
using InvoiceMaster.Core.Entities;
|
using FiscalFlow.Core.Entities;
|
||||||
using InvoiceMaster.Core.Interfaces;
|
using FiscalFlow.Core.Interfaces;
|
||||||
using InvoiceMaster.Integrations.Accounting;
|
using FiscalFlow.Integrations.Accounting;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace InvoiceMaster.Application.Commands.Invoices;
|
namespace FiscalFlow.Application.Commands.Invoices;
|
||||||
|
|
||||||
public record ImportInvoiceCommand(
|
public record ImportInvoiceCommand(
|
||||||
Guid InvoiceId,
|
Guid InvoiceId,
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
using InvoiceMaster.Application.DTOs;
|
using FiscalFlow.Application.DTOs;
|
||||||
using InvoiceMaster.Core.Entities;
|
using FiscalFlow.Core.Entities;
|
||||||
using InvoiceMaster.Core.Interfaces;
|
using FiscalFlow.Core.Interfaces;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
|
|
||||||
namespace InvoiceMaster.Application.Commands.Invoices;
|
namespace FiscalFlow.Application.Commands.Invoices;
|
||||||
|
|
||||||
public record UploadInvoiceCommand(
|
public record UploadInvoiceCommand(
|
||||||
Guid UserId,
|
Guid UserId,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace InvoiceMaster.Application.DTOs;
|
namespace FiscalFlow.Application.DTOs;
|
||||||
|
|
||||||
public record UserDto(
|
public record UserDto(
|
||||||
Guid Id,
|
Guid Id,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace InvoiceMaster.Application.DTOs;
|
namespace FiscalFlow.Application.DTOs;
|
||||||
|
|
||||||
public record ConnectionDto(
|
public record ConnectionDto(
|
||||||
string Provider,
|
string Provider,
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using InvoiceMaster.Core.Entities;
|
using FiscalFlow.Core.Entities;
|
||||||
|
|
||||||
namespace InvoiceMaster.Application.DTOs;
|
namespace FiscalFlow.Application.DTOs;
|
||||||
|
|
||||||
public record InvoiceListItemDto(
|
public record InvoiceListItemDto(
|
||||||
Guid Id,
|
Guid Id,
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using InvoiceMaster.Application.Services;
|
using InvoiceMaster.Application.Services;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace InvoiceMaster.Application;
|
namespace FiscalFlow.Application;
|
||||||
|
|
||||||
public static class DependencyInjection
|
public static class DependencyInjection
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<AssemblyName>FiscalFlow.Application</AssemblyName>
|
||||||
|
<RootNamespace>FiscalFlow.Application</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="MediatR" Version="12.4.1" />
|
||||||
|
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||||
|
<PackageReference Include="FluentValidation" Version="11.11.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\FiscalFlow.Core\FiscalFlow.Core.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using InvoiceMaster.Application.Commands.Auth;
|
using FiscalFlow.Application.Commands.Auth;
|
||||||
using InvoiceMaster.Core.Entities;
|
using FiscalFlow.Core.Entities;
|
||||||
using InvoiceMaster.Core.Interfaces;
|
using FiscalFlow.Core.Interfaces;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
@@ -8,7 +8,7 @@ using System.Security.Claims;
|
|||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace InvoiceMaster.Application.Services;
|
namespace FiscalFlow.Application.Services;
|
||||||
|
|
||||||
public interface IAuthService
|
public interface IAuthService
|
||||||
{
|
{
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
using InvoiceMaster.Core.Entities;
|
using FiscalFlow.Core.Entities;
|
||||||
using InvoiceMaster.Core.Interfaces;
|
using FiscalFlow.Core.Interfaces;
|
||||||
using InvoiceMaster.Integrations.Accounting;
|
using FiscalFlow.Integrations.Accounting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace InvoiceMaster.Application.Services;
|
namespace FiscalFlow.Application.Services;
|
||||||
|
|
||||||
public interface ISupplierMatchingService
|
public interface ISupplierMatchingService
|
||||||
{
|
{
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using InvoiceMaster.Core.Entities;
|
using FiscalFlow.Core.Entities;
|
||||||
using InvoiceMaster.Integrations.Accounting;
|
using FiscalFlow.Integrations.Accounting;
|
||||||
|
|
||||||
namespace InvoiceMaster.Application.Services;
|
namespace FiscalFlow.Application.Services;
|
||||||
|
|
||||||
public interface IVoucherGenerationService
|
public interface IVoucherGenerationService
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// <autogenerated />
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
[assembly: System.Reflection.AssemblyCompanyAttribute("FiscalFlow.Application")]
|
||||||
|
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||||
|
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||||
|
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+05ea67144f6a97e372ca4293ce2393e15a3f6bb7")]
|
||||||
|
[assembly: System.Reflection.AssemblyProductAttribute("FiscalFlow.Application")]
|
||||||
|
[assembly: System.Reflection.AssemblyTitleAttribute("FiscalFlow.Application")]
|
||||||
|
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||||
|
|
||||||
|
// Generated by the MSBuild WriteCodeFragment class.
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
c2db443b065091a7cf58a98ba76a2c433babcdae60eec34974f9402144d9f746
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
is_global = true
|
||||||
|
build_property.TargetFramework = net8.0
|
||||||
|
build_property.TargetFrameworkIdentifier = .NETCoreApp
|
||||||
|
build_property.TargetFrameworkVersion = v8.0
|
||||||
|
build_property.TargetPlatformMinVersion =
|
||||||
|
build_property.UsingMicrosoftNETSdkWeb =
|
||||||
|
build_property.ProjectTypeGuids =
|
||||||
|
build_property.InvariantGlobalization =
|
||||||
|
build_property.PlatformNeutralAssembly =
|
||||||
|
build_property.EnforceExtendedAnalyzerRules =
|
||||||
|
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||||
|
build_property.RootNamespace = FiscalFlow.Application
|
||||||
|
build_property.ProjectDir = C:\Users\yaoji\git\ColaCoder\accounting-system\backend\src\InvoiceMaster.Application\
|
||||||
|
build_property.EnableComHosting =
|
||||||
|
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||||
|
build_property.EffectiveAnalysisLevelStyle = 8.0
|
||||||
|
build_property.EnableCodeStyleSeverity =
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,178 @@
|
|||||||
|
{
|
||||||
|
"format": 1,
|
||||||
|
"restore": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj": {}
|
||||||
|
},
|
||||||
|
"projects": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"projectName": "InvoiceMaster.Application",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"packagesPath": "C:\\Users\\yaoji\\.nuget\\packages\\",
|
||||||
|
"outputPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\obj\\",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"fallbackFolders": [
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||||
|
],
|
||||||
|
"configFilePaths": [
|
||||||
|
"C:\\Users\\yaoji\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net8.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||||
|
"https://api.nuget.org/v3/index.json": {},
|
||||||
|
"https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"projectReferences": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj": {
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"allWarningsAsErrors": true,
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restoreAuditProperties": {
|
||||||
|
"enableAudit": "true",
|
||||||
|
"auditLevel": "low",
|
||||||
|
"auditMode": "direct"
|
||||||
|
},
|
||||||
|
"SdkAnalysisLevel": "10.0.100"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"dependencies": {
|
||||||
|
"AutoMapper": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[12.0.1, )"
|
||||||
|
},
|
||||||
|
"FluentValidation": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[11.8.1, )"
|
||||||
|
},
|
||||||
|
"MediatR": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[12.2.0, )"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"StyleCop.Analyzers": {
|
||||||
|
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
|
||||||
|
"suppressParent": "All",
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[1.2.0-beta.556, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48",
|
||||||
|
"net481"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.102/PortableRuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"projectName": "InvoiceMaster.Core",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"packagesPath": "C:\\Users\\yaoji\\.nuget\\packages\\",
|
||||||
|
"outputPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\obj\\",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"fallbackFolders": [
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||||
|
],
|
||||||
|
"configFilePaths": [
|
||||||
|
"C:\\Users\\yaoji\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net8.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||||
|
"https://api.nuget.org/v3/index.json": {},
|
||||||
|
"https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"projectReferences": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"allWarningsAsErrors": true,
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restoreAuditProperties": {
|
||||||
|
"enableAudit": "true",
|
||||||
|
"auditLevel": "low",
|
||||||
|
"auditMode": "direct"
|
||||||
|
},
|
||||||
|
"SdkAnalysisLevel": "10.0.100"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"dependencies": {
|
||||||
|
"StyleCop.Analyzers": {
|
||||||
|
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
|
||||||
|
"suppressParent": "All",
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[1.2.0-beta.556, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48",
|
||||||
|
"net481"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.102/PortableRuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||||
|
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||||
|
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||||
|
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||||
|
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\yaoji\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
|
||||||
|
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||||
|
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<SourceRoot Include="C:\Users\yaoji\.nuget\packages\" />
|
||||||
|
<SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<PkgStyleCop_Analyzers_Unstable Condition=" '$(PkgStyleCop_Analyzers_Unstable)' == '' ">C:\Users\yaoji\.nuget\packages\stylecop.analyzers.unstable\1.2.0.556</PkgStyleCop_Analyzers_Unstable>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
|
||||||
466
backend/src/FiscalFlow.Application/obj/project.assets.json
Normal file
466
backend/src/FiscalFlow.Application/obj/project.assets.json
Normal file
@@ -0,0 +1,466 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"targets": {
|
||||||
|
"net8.0": {
|
||||||
|
"AutoMapper/12.0.1": {
|
||||||
|
"type": "package",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.CSharp": "4.7.0"
|
||||||
|
},
|
||||||
|
"compile": {
|
||||||
|
"lib/netstandard2.1/AutoMapper.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.1/AutoMapper.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"FluentValidation/11.8.1": {
|
||||||
|
"type": "package",
|
||||||
|
"compile": {
|
||||||
|
"lib/net7.0/FluentValidation.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net7.0/FluentValidation.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"MediatR/12.2.0": {
|
||||||
|
"type": "package",
|
||||||
|
"dependencies": {
|
||||||
|
"MediatR.Contracts": "[2.0.1, 3.0.0)",
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
|
||||||
|
},
|
||||||
|
"compile": {
|
||||||
|
"lib/net6.0/MediatR.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net6.0/MediatR.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"MediatR.Contracts/2.0.1": {
|
||||||
|
"type": "package",
|
||||||
|
"compile": {
|
||||||
|
"lib/netstandard2.0/MediatR.Contracts.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/MediatR.Contracts.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.CSharp/4.7.0": {
|
||||||
|
"type": "package",
|
||||||
|
"compile": {
|
||||||
|
"ref/netcoreapp2.0/_._": {}
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netcoreapp2.0/_._": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": {
|
||||||
|
"type": "package",
|
||||||
|
"compile": {
|
||||||
|
"lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"buildTransitive/net6.0/_._": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"StyleCop.Analyzers/1.2.0-beta.556": {
|
||||||
|
"type": "package",
|
||||||
|
"dependencies": {
|
||||||
|
"StyleCop.Analyzers.Unstable": "1.2.0.556"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"StyleCop.Analyzers.Unstable/1.2.0.556": {
|
||||||
|
"type": "package"
|
||||||
|
},
|
||||||
|
"InvoiceMaster.Core/1.0.0": {
|
||||||
|
"type": "project",
|
||||||
|
"framework": ".NETCoreApp,Version=v8.0",
|
||||||
|
"compile": {
|
||||||
|
"bin/placeholder/InvoiceMaster.Core.dll": {}
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"bin/placeholder/InvoiceMaster.Core.dll": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libraries": {
|
||||||
|
"AutoMapper/12.0.1": {
|
||||||
|
"sha512": "hvV62vl6Hp/WfQ24yzo3Co9+OPl8wH8hApwVtgWpiAynVJkUcs7xvehnSftawL8Pe8FrPffBRM3hwzLQqWDNjA==",
|
||||||
|
"type": "package",
|
||||||
|
"path": "automapper/12.0.1",
|
||||||
|
"files": [
|
||||||
|
".nupkg.metadata",
|
||||||
|
".signature.p7s",
|
||||||
|
"README.md",
|
||||||
|
"automapper.12.0.1.nupkg.sha512",
|
||||||
|
"automapper.nuspec",
|
||||||
|
"icon.png",
|
||||||
|
"lib/netstandard2.1/AutoMapper.dll",
|
||||||
|
"lib/netstandard2.1/AutoMapper.xml"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"FluentValidation/11.8.1": {
|
||||||
|
"sha512": "N72rnlE99XYB7EGA1u9y7m7kNTTynqOPBhZqDE8zr1Y0aSR4t5si94LRA7UVdAV09GaXWCErW+EiFhfbg3DSbg==",
|
||||||
|
"type": "package",
|
||||||
|
"path": "fluentvalidation/11.8.1",
|
||||||
|
"files": [
|
||||||
|
".nupkg.metadata",
|
||||||
|
".signature.p7s",
|
||||||
|
"README.md",
|
||||||
|
"fluent-validation-icon.png",
|
||||||
|
"fluentvalidation.11.8.1.nupkg.sha512",
|
||||||
|
"fluentvalidation.nuspec",
|
||||||
|
"lib/net5.0/FluentValidation.dll",
|
||||||
|
"lib/net5.0/FluentValidation.xml",
|
||||||
|
"lib/net6.0/FluentValidation.dll",
|
||||||
|
"lib/net6.0/FluentValidation.xml",
|
||||||
|
"lib/net7.0/FluentValidation.dll",
|
||||||
|
"lib/net7.0/FluentValidation.xml",
|
||||||
|
"lib/netstandard2.0/FluentValidation.dll",
|
||||||
|
"lib/netstandard2.0/FluentValidation.xml",
|
||||||
|
"lib/netstandard2.1/FluentValidation.dll",
|
||||||
|
"lib/netstandard2.1/FluentValidation.xml"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"MediatR/12.2.0": {
|
||||||
|
"sha512": "8TUFrHapKi6D74PhnSNEguRsH91HNGyP3R4ZQdgDorJgl9Wac5Prh0vA33QfrniAaS6L2xNNhc6vxzg+5AIbwA==",
|
||||||
|
"type": "package",
|
||||||
|
"path": "mediatr/12.2.0",
|
||||||
|
"files": [
|
||||||
|
".nupkg.metadata",
|
||||||
|
".signature.p7s",
|
||||||
|
"gradient_128x128.png",
|
||||||
|
"lib/net6.0/MediatR.dll",
|
||||||
|
"lib/net6.0/MediatR.xml",
|
||||||
|
"lib/netstandard2.0/MediatR.dll",
|
||||||
|
"lib/netstandard2.0/MediatR.xml",
|
||||||
|
"mediatr.12.2.0.nupkg.sha512",
|
||||||
|
"mediatr.nuspec"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"MediatR.Contracts/2.0.1": {
|
||||||
|
"sha512": "FYv95bNT4UwcNA+G/J1oX5OpRiSUxteXaUt2BJbRSdRNiIUNbggJF69wy6mnk2wYToaanpdXZdCwVylt96MpwQ==",
|
||||||
|
"type": "package",
|
||||||
|
"path": "mediatr.contracts/2.0.1",
|
||||||
|
"files": [
|
||||||
|
".nupkg.metadata",
|
||||||
|
".signature.p7s",
|
||||||
|
"gradient_128x128.png",
|
||||||
|
"lib/netstandard2.0/MediatR.Contracts.dll",
|
||||||
|
"lib/netstandard2.0/MediatR.Contracts.xml",
|
||||||
|
"mediatr.contracts.2.0.1.nupkg.sha512",
|
||||||
|
"mediatr.contracts.nuspec"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Microsoft.CSharp/4.7.0": {
|
||||||
|
"sha512": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA==",
|
||||||
|
"type": "package",
|
||||||
|
"path": "microsoft.csharp/4.7.0",
|
||||||
|
"files": [
|
||||||
|
".nupkg.metadata",
|
||||||
|
".signature.p7s",
|
||||||
|
"LICENSE.TXT",
|
||||||
|
"THIRD-PARTY-NOTICES.TXT",
|
||||||
|
"lib/MonoAndroid10/_._",
|
||||||
|
"lib/MonoTouch10/_._",
|
||||||
|
"lib/net45/_._",
|
||||||
|
"lib/netcore50/Microsoft.CSharp.dll",
|
||||||
|
"lib/netcoreapp2.0/_._",
|
||||||
|
"lib/netstandard1.3/Microsoft.CSharp.dll",
|
||||||
|
"lib/netstandard2.0/Microsoft.CSharp.dll",
|
||||||
|
"lib/netstandard2.0/Microsoft.CSharp.xml",
|
||||||
|
"lib/portable-net45+win8+wp8+wpa81/_._",
|
||||||
|
"lib/uap10.0.16299/_._",
|
||||||
|
"lib/win8/_._",
|
||||||
|
"lib/wp80/_._",
|
||||||
|
"lib/wpa81/_._",
|
||||||
|
"lib/xamarinios10/_._",
|
||||||
|
"lib/xamarinmac20/_._",
|
||||||
|
"lib/xamarintvos10/_._",
|
||||||
|
"lib/xamarinwatchos10/_._",
|
||||||
|
"microsoft.csharp.4.7.0.nupkg.sha512",
|
||||||
|
"microsoft.csharp.nuspec",
|
||||||
|
"ref/MonoAndroid10/_._",
|
||||||
|
"ref/MonoTouch10/_._",
|
||||||
|
"ref/net45/_._",
|
||||||
|
"ref/netcore50/Microsoft.CSharp.dll",
|
||||||
|
"ref/netcore50/Microsoft.CSharp.xml",
|
||||||
|
"ref/netcore50/de/Microsoft.CSharp.xml",
|
||||||
|
"ref/netcore50/es/Microsoft.CSharp.xml",
|
||||||
|
"ref/netcore50/fr/Microsoft.CSharp.xml",
|
||||||
|
"ref/netcore50/it/Microsoft.CSharp.xml",
|
||||||
|
"ref/netcore50/ja/Microsoft.CSharp.xml",
|
||||||
|
"ref/netcore50/ko/Microsoft.CSharp.xml",
|
||||||
|
"ref/netcore50/ru/Microsoft.CSharp.xml",
|
||||||
|
"ref/netcore50/zh-hans/Microsoft.CSharp.xml",
|
||||||
|
"ref/netcore50/zh-hant/Microsoft.CSharp.xml",
|
||||||
|
"ref/netcoreapp2.0/_._",
|
||||||
|
"ref/netstandard1.0/Microsoft.CSharp.dll",
|
||||||
|
"ref/netstandard1.0/Microsoft.CSharp.xml",
|
||||||
|
"ref/netstandard1.0/de/Microsoft.CSharp.xml",
|
||||||
|
"ref/netstandard1.0/es/Microsoft.CSharp.xml",
|
||||||
|
"ref/netstandard1.0/fr/Microsoft.CSharp.xml",
|
||||||
|
"ref/netstandard1.0/it/Microsoft.CSharp.xml",
|
||||||
|
"ref/netstandard1.0/ja/Microsoft.CSharp.xml",
|
||||||
|
"ref/netstandard1.0/ko/Microsoft.CSharp.xml",
|
||||||
|
"ref/netstandard1.0/ru/Microsoft.CSharp.xml",
|
||||||
|
"ref/netstandard1.0/zh-hans/Microsoft.CSharp.xml",
|
||||||
|
"ref/netstandard1.0/zh-hant/Microsoft.CSharp.xml",
|
||||||
|
"ref/netstandard2.0/Microsoft.CSharp.dll",
|
||||||
|
"ref/netstandard2.0/Microsoft.CSharp.xml",
|
||||||
|
"ref/portable-net45+win8+wp8+wpa81/_._",
|
||||||
|
"ref/uap10.0.16299/_._",
|
||||||
|
"ref/win8/_._",
|
||||||
|
"ref/wp80/_._",
|
||||||
|
"ref/wpa81/_._",
|
||||||
|
"ref/xamarinios10/_._",
|
||||||
|
"ref/xamarinmac20/_._",
|
||||||
|
"ref/xamarintvos10/_._",
|
||||||
|
"ref/xamarinwatchos10/_._",
|
||||||
|
"useSharedDesignerContext.txt",
|
||||||
|
"version.txt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": {
|
||||||
|
"sha512": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==",
|
||||||
|
"type": "package",
|
||||||
|
"path": "microsoft.extensions.dependencyinjection.abstractions/8.0.0",
|
||||||
|
"files": [
|
||||||
|
".nupkg.metadata",
|
||||||
|
".signature.p7s",
|
||||||
|
"Icon.png",
|
||||||
|
"LICENSE.TXT",
|
||||||
|
"PACKAGE.md",
|
||||||
|
"THIRD-PARTY-NOTICES.TXT",
|
||||||
|
"buildTransitive/net461/Microsoft.Extensions.DependencyInjection.Abstractions.targets",
|
||||||
|
"buildTransitive/net462/_._",
|
||||||
|
"buildTransitive/net6.0/_._",
|
||||||
|
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.Abstractions.targets",
|
||||||
|
"lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
|
||||||
|
"lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
|
||||||
|
"lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
|
||||||
|
"lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
|
||||||
|
"lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
|
||||||
|
"lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
|
||||||
|
"lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
|
||||||
|
"lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
|
||||||
|
"lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
|
||||||
|
"lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
|
||||||
|
"lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
|
||||||
|
"lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
|
||||||
|
"microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"microsoft.extensions.dependencyinjection.abstractions.nuspec",
|
||||||
|
"useSharedDesignerContext.txt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"StyleCop.Analyzers/1.2.0-beta.556": {
|
||||||
|
"sha512": "llRPgmA1fhC0I0QyFLEcjvtM2239QzKr/tcnbsjArLMJxJlu0AA5G7Fft0OI30pHF3MW63Gf4aSSsjc5m82J1Q==",
|
||||||
|
"type": "package",
|
||||||
|
"path": "stylecop.analyzers/1.2.0-beta.556",
|
||||||
|
"files": [
|
||||||
|
".nupkg.metadata",
|
||||||
|
".signature.p7s",
|
||||||
|
"LICENSE",
|
||||||
|
"THIRD-PARTY-NOTICES.txt",
|
||||||
|
"stylecop.analyzers.1.2.0-beta.556.nupkg.sha512",
|
||||||
|
"stylecop.analyzers.nuspec"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"StyleCop.Analyzers.Unstable/1.2.0.556": {
|
||||||
|
"sha512": "zvn9Mqs/ox/83cpYPignI8hJEM2A93s2HkHs8HYMOAQW0PkampyoErAiIyKxgTLqbbad29HX/shv/6LGSjPJNQ==",
|
||||||
|
"type": "package",
|
||||||
|
"path": "stylecop.analyzers.unstable/1.2.0.556",
|
||||||
|
"hasTools": true,
|
||||||
|
"files": [
|
||||||
|
".nupkg.metadata",
|
||||||
|
".signature.p7s",
|
||||||
|
"LICENSE",
|
||||||
|
"THIRD-PARTY-NOTICES.txt",
|
||||||
|
"analyzers/dotnet/cs/StyleCop.Analyzers.CodeFixes.dll",
|
||||||
|
"analyzers/dotnet/cs/StyleCop.Analyzers.dll",
|
||||||
|
"analyzers/dotnet/cs/de-DE/StyleCop.Analyzers.resources.dll",
|
||||||
|
"analyzers/dotnet/cs/en-GB/StyleCop.Analyzers.resources.dll",
|
||||||
|
"analyzers/dotnet/cs/es-MX/StyleCop.Analyzers.resources.dll",
|
||||||
|
"analyzers/dotnet/cs/fr-FR/StyleCop.Analyzers.resources.dll",
|
||||||
|
"analyzers/dotnet/cs/pl-PL/StyleCop.Analyzers.resources.dll",
|
||||||
|
"analyzers/dotnet/cs/pt-BR/StyleCop.Analyzers.resources.dll",
|
||||||
|
"analyzers/dotnet/cs/ru-RU/StyleCop.Analyzers.resources.dll",
|
||||||
|
"rulesets/StyleCopAnalyzersDefault.ruleset",
|
||||||
|
"stylecop.analyzers.unstable.1.2.0.556.nupkg.sha512",
|
||||||
|
"stylecop.analyzers.unstable.nuspec",
|
||||||
|
"tools/install.ps1",
|
||||||
|
"tools/uninstall.ps1"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"InvoiceMaster.Core/1.0.0": {
|
||||||
|
"type": "project",
|
||||||
|
"path": "../InvoiceMaster.Core/InvoiceMaster.Core.csproj",
|
||||||
|
"msbuildProject": "../InvoiceMaster.Core/InvoiceMaster.Core.csproj"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"projectFileDependencyGroups": {
|
||||||
|
"net8.0": [
|
||||||
|
"AutoMapper >= 12.0.1",
|
||||||
|
"FluentValidation >= 11.8.1",
|
||||||
|
"InvoiceMaster.Core >= 1.0.0",
|
||||||
|
"MediatR >= 12.2.0",
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions >= 8.0.0",
|
||||||
|
"StyleCop.Analyzers >= 1.2.0-beta.556"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"packageFolders": {
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\": {},
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {}
|
||||||
|
},
|
||||||
|
"project": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"projectName": "InvoiceMaster.Application",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"packagesPath": "C:\\Users\\yaoji\\.nuget\\packages\\",
|
||||||
|
"outputPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\obj\\",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"fallbackFolders": [
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||||
|
],
|
||||||
|
"configFilePaths": [
|
||||||
|
"C:\\Users\\yaoji\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net8.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||||
|
"https://api.nuget.org/v3/index.json": {},
|
||||||
|
"https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"projectReferences": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj": {
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"allWarningsAsErrors": true,
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restoreAuditProperties": {
|
||||||
|
"enableAudit": "true",
|
||||||
|
"auditLevel": "low",
|
||||||
|
"auditMode": "direct"
|
||||||
|
},
|
||||||
|
"SdkAnalysisLevel": "10.0.100"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"dependencies": {
|
||||||
|
"AutoMapper": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[12.0.1, )"
|
||||||
|
},
|
||||||
|
"FluentValidation": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[11.8.1, )"
|
||||||
|
},
|
||||||
|
"MediatR": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[12.2.0, )"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"StyleCop.Analyzers": {
|
||||||
|
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
|
||||||
|
"suppressParent": "All",
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[1.2.0-beta.556, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48",
|
||||||
|
"net481"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.102/PortableRuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"logs": [
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1900",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Warning As Error: Error occurred while getting package vulnerability data: Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
66
backend/src/FiscalFlow.Application/obj/project.nuget.cache
Normal file
66
backend/src/FiscalFlow.Application/obj/project.nuget.cache
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"dgSpecHash": "azpiw38zbcw=",
|
||||||
|
"success": false,
|
||||||
|
"projectFilePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"expectedPackageFiles": [
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\automapper\\12.0.1\\automapper.12.0.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\fluentvalidation\\11.8.1\\fluentvalidation.11.8.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\mediatr\\12.2.0\\mediatr.12.2.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\mediatr.contracts\\2.0.1\\mediatr.contracts.2.0.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.csharp\\4.7.0\\microsoft.csharp.4.7.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.dependencyinjection.abstractions\\8.0.0\\microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\stylecop.analyzers\\1.2.0-beta.556\\stylecop.analyzers.1.2.0-beta.556.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\stylecop.analyzers.unstable\\1.2.0.556\\stylecop.analyzers.unstable.1.2.0.556.nupkg.sha512"
|
||||||
|
],
|
||||||
|
"logs": [
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1900",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Warning As Error: Error occurred while getting package vulnerability data: Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace InvoiceMaster.Core.Entities;
|
namespace FiscalFlow.Core.Entities;
|
||||||
|
|
||||||
public class AccountingConnection : BaseEntity
|
public class AccountingConnection : BaseEntity
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace InvoiceMaster.Core.Entities;
|
namespace FiscalFlow.Core.Entities;
|
||||||
|
|
||||||
public abstract class BaseEntity
|
public abstract class BaseEntity
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace InvoiceMaster.Core.Entities;
|
namespace FiscalFlow.Core.Entities;
|
||||||
|
|
||||||
public enum InvoiceStatus
|
public enum InvoiceStatus
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace InvoiceMaster.Core.Entities;
|
namespace FiscalFlow.Core.Entities;
|
||||||
|
|
||||||
public class SupplierCache : BaseEntity
|
public class SupplierCache : BaseEntity
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace InvoiceMaster.Core.Entities;
|
namespace FiscalFlow.Core.Entities;
|
||||||
|
|
||||||
public class User : BaseEntity
|
public class User : BaseEntity
|
||||||
{
|
{
|
||||||
8
backend/src/FiscalFlow.Core/FiscalFlow.Core.csproj
Normal file
8
backend/src/FiscalFlow.Core/FiscalFlow.Core.csproj
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<AssemblyName>FiscalFlow.Core</AssemblyName>
|
||||||
|
<RootNamespace>FiscalFlow.Core</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace InvoiceMaster.Core.Interfaces;
|
namespace FiscalFlow.Core.Interfaces;
|
||||||
|
|
||||||
public interface IBlobStorageService
|
public interface IBlobStorageService
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace InvoiceMaster.Core.Interfaces;
|
namespace FiscalFlow.Core.Interfaces;
|
||||||
|
|
||||||
public interface IOcrService
|
public interface IOcrService
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace InvoiceMaster.Core.Interfaces;
|
namespace FiscalFlow.Core.Interfaces;
|
||||||
|
|
||||||
public interface IRepository<T> where T : class
|
public interface IRepository<T> where T : class
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace InvoiceMaster.Core.Interfaces;
|
namespace FiscalFlow.Core.Interfaces;
|
||||||
|
|
||||||
public interface IUnitOfWork : IDisposable
|
public interface IUnitOfWork : IDisposable
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// <autogenerated />
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
[assembly: System.Reflection.AssemblyCompanyAttribute("FiscalFlow.Core")]
|
||||||
|
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||||
|
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||||
|
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+05ea67144f6a97e372ca4293ce2393e15a3f6bb7")]
|
||||||
|
[assembly: System.Reflection.AssemblyProductAttribute("FiscalFlow.Core")]
|
||||||
|
[assembly: System.Reflection.AssemblyTitleAttribute("FiscalFlow.Core")]
|
||||||
|
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||||
|
|
||||||
|
// Generated by the MSBuild WriteCodeFragment class.
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
92b6dc48ee9fbbbbfbde6aaa4bddd2ee625d380442ab3e848bc8acc076c5c1f6
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
is_global = true
|
||||||
|
build_property.TargetFramework = net8.0
|
||||||
|
build_property.TargetFrameworkIdentifier = .NETCoreApp
|
||||||
|
build_property.TargetFrameworkVersion = v8.0
|
||||||
|
build_property.TargetPlatformMinVersion =
|
||||||
|
build_property.UsingMicrosoftNETSdkWeb =
|
||||||
|
build_property.ProjectTypeGuids =
|
||||||
|
build_property.InvariantGlobalization =
|
||||||
|
build_property.PlatformNeutralAssembly =
|
||||||
|
build_property.EnforceExtendedAnalyzerRules =
|
||||||
|
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||||
|
build_property.RootNamespace = FiscalFlow.Core
|
||||||
|
build_property.ProjectDir = C:\Users\yaoji\git\ColaCoder\accounting-system\backend\src\InvoiceMaster.Core\
|
||||||
|
build_property.EnableComHosting =
|
||||||
|
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||||
|
build_property.EffectiveAnalysisLevelStyle = 8.0
|
||||||
|
build_property.EnableCodeStyleSeverity =
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// <auto-generated/>
|
||||||
|
global using System;
|
||||||
|
global using System.Collections.Generic;
|
||||||
|
global using System.IO;
|
||||||
|
global using System.Linq;
|
||||||
|
global using System.Net.Http;
|
||||||
|
global using System.Threading;
|
||||||
|
global using System.Threading.Tasks;
|
||||||
Binary file not shown.
@@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
"format": 1,
|
||||||
|
"restore": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj": {}
|
||||||
|
},
|
||||||
|
"projects": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"projectName": "InvoiceMaster.Core",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"packagesPath": "C:\\Users\\yaoji\\.nuget\\packages\\",
|
||||||
|
"outputPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\obj\\",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"fallbackFolders": [
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||||
|
],
|
||||||
|
"configFilePaths": [
|
||||||
|
"C:\\Users\\yaoji\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net8.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||||
|
"https://api.nuget.org/v3/index.json": {},
|
||||||
|
"https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"projectReferences": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"allWarningsAsErrors": true,
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restoreAuditProperties": {
|
||||||
|
"enableAudit": "true",
|
||||||
|
"auditLevel": "low",
|
||||||
|
"auditMode": "direct"
|
||||||
|
},
|
||||||
|
"SdkAnalysisLevel": "10.0.100"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"dependencies": {
|
||||||
|
"StyleCop.Analyzers": {
|
||||||
|
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
|
||||||
|
"suppressParent": "All",
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[1.2.0-beta.556, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48",
|
||||||
|
"net481"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.102/PortableRuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||||
|
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||||
|
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||||
|
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||||
|
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\yaoji\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
|
||||||
|
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||||
|
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<SourceRoot Include="C:\Users\yaoji\.nuget\packages\" />
|
||||||
|
<SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<PkgStyleCop_Analyzers_Unstable Condition=" '$(PkgStyleCop_Analyzers_Unstable)' == '' ">C:\Users\yaoji\.nuget\packages\stylecop.analyzers.unstable\1.2.0.556</PkgStyleCop_Analyzers_Unstable>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
|
||||||
168
backend/src/FiscalFlow.Core/obj/project.assets.json
Normal file
168
backend/src/FiscalFlow.Core/obj/project.assets.json
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"targets": {
|
||||||
|
"net8.0": {
|
||||||
|
"StyleCop.Analyzers/1.2.0-beta.556": {
|
||||||
|
"type": "package",
|
||||||
|
"dependencies": {
|
||||||
|
"StyleCop.Analyzers.Unstable": "1.2.0.556"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"StyleCop.Analyzers.Unstable/1.2.0.556": {
|
||||||
|
"type": "package"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libraries": {
|
||||||
|
"StyleCop.Analyzers/1.2.0-beta.556": {
|
||||||
|
"sha512": "llRPgmA1fhC0I0QyFLEcjvtM2239QzKr/tcnbsjArLMJxJlu0AA5G7Fft0OI30pHF3MW63Gf4aSSsjc5m82J1Q==",
|
||||||
|
"type": "package",
|
||||||
|
"path": "stylecop.analyzers/1.2.0-beta.556",
|
||||||
|
"files": [
|
||||||
|
".nupkg.metadata",
|
||||||
|
".signature.p7s",
|
||||||
|
"LICENSE",
|
||||||
|
"THIRD-PARTY-NOTICES.txt",
|
||||||
|
"stylecop.analyzers.1.2.0-beta.556.nupkg.sha512",
|
||||||
|
"stylecop.analyzers.nuspec"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"StyleCop.Analyzers.Unstable/1.2.0.556": {
|
||||||
|
"sha512": "zvn9Mqs/ox/83cpYPignI8hJEM2A93s2HkHs8HYMOAQW0PkampyoErAiIyKxgTLqbbad29HX/shv/6LGSjPJNQ==",
|
||||||
|
"type": "package",
|
||||||
|
"path": "stylecop.analyzers.unstable/1.2.0.556",
|
||||||
|
"hasTools": true,
|
||||||
|
"files": [
|
||||||
|
".nupkg.metadata",
|
||||||
|
".signature.p7s",
|
||||||
|
"LICENSE",
|
||||||
|
"THIRD-PARTY-NOTICES.txt",
|
||||||
|
"analyzers/dotnet/cs/StyleCop.Analyzers.CodeFixes.dll",
|
||||||
|
"analyzers/dotnet/cs/StyleCop.Analyzers.dll",
|
||||||
|
"analyzers/dotnet/cs/de-DE/StyleCop.Analyzers.resources.dll",
|
||||||
|
"analyzers/dotnet/cs/en-GB/StyleCop.Analyzers.resources.dll",
|
||||||
|
"analyzers/dotnet/cs/es-MX/StyleCop.Analyzers.resources.dll",
|
||||||
|
"analyzers/dotnet/cs/fr-FR/StyleCop.Analyzers.resources.dll",
|
||||||
|
"analyzers/dotnet/cs/pl-PL/StyleCop.Analyzers.resources.dll",
|
||||||
|
"analyzers/dotnet/cs/pt-BR/StyleCop.Analyzers.resources.dll",
|
||||||
|
"analyzers/dotnet/cs/ru-RU/StyleCop.Analyzers.resources.dll",
|
||||||
|
"rulesets/StyleCopAnalyzersDefault.ruleset",
|
||||||
|
"stylecop.analyzers.unstable.1.2.0.556.nupkg.sha512",
|
||||||
|
"stylecop.analyzers.unstable.nuspec",
|
||||||
|
"tools/install.ps1",
|
||||||
|
"tools/uninstall.ps1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"projectFileDependencyGroups": {
|
||||||
|
"net8.0": [
|
||||||
|
"StyleCop.Analyzers >= 1.2.0-beta.556"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"packageFolders": {
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\": {},
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {}
|
||||||
|
},
|
||||||
|
"project": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"projectName": "InvoiceMaster.Core",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"packagesPath": "C:\\Users\\yaoji\\.nuget\\packages\\",
|
||||||
|
"outputPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\obj\\",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"fallbackFolders": [
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||||
|
],
|
||||||
|
"configFilePaths": [
|
||||||
|
"C:\\Users\\yaoji\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net8.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||||
|
"https://api.nuget.org/v3/index.json": {},
|
||||||
|
"https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"projectReferences": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"allWarningsAsErrors": true,
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restoreAuditProperties": {
|
||||||
|
"enableAudit": "true",
|
||||||
|
"auditLevel": "low",
|
||||||
|
"auditMode": "direct"
|
||||||
|
},
|
||||||
|
"SdkAnalysisLevel": "10.0.100"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"dependencies": {
|
||||||
|
"StyleCop.Analyzers": {
|
||||||
|
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
|
||||||
|
"suppressParent": "All",
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[1.2.0-beta.556, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48",
|
||||||
|
"net481"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.102/PortableRuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"logs": [
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1900",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Warning As Error: Error occurred while getting package vulnerability data: Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
52
backend/src/FiscalFlow.Core/obj/project.nuget.cache
Normal file
52
backend/src/FiscalFlow.Core/obj/project.nuget.cache
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"dgSpecHash": "SGe3B4fOk7A=",
|
||||||
|
"success": false,
|
||||||
|
"projectFilePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"expectedPackageFiles": [
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\stylecop.analyzers\\1.2.0-beta.556\\stylecop.analyzers.1.2.0-beta.556.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\stylecop.analyzers.unstable\\1.2.0.556\\stylecop.analyzers.unstable.1.2.0.556.nupkg.sha512"
|
||||||
|
],
|
||||||
|
"logs": [
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1900",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Warning As Error: Error occurred while getting package vulnerability data: Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using InvoiceMaster.Core.Entities;
|
using FiscalFlow.Core.Entities;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace InvoiceMaster.Infrastructure.Data;
|
namespace FiscalFlow.Infrastructure.Data;
|
||||||
|
|
||||||
public class ApplicationDbContext : DbContext
|
public class ApplicationDbContext : DbContext
|
||||||
{
|
{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using InvoiceMaster.Core.Entities;
|
using FiscalFlow.Core.Entities;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
|
||||||
namespace InvoiceMaster.Infrastructure.Data.Configurations;
|
namespace FiscalFlow.Infrastructure.Data.Configurations;
|
||||||
|
|
||||||
public class AccountingConnectionConfiguration : IEntityTypeConfiguration<AccountingConnection>
|
public class AccountingConnectionConfiguration : IEntityTypeConfiguration<AccountingConnection>
|
||||||
{
|
{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using InvoiceMaster.Core.Entities;
|
using FiscalFlow.Core.Entities;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
|
||||||
namespace InvoiceMaster.Infrastructure.Data.Configurations;
|
namespace FiscalFlow.Infrastructure.Data.Configurations;
|
||||||
|
|
||||||
public class InvoiceConfiguration : IEntityTypeConfiguration<Invoice>
|
public class InvoiceConfiguration : IEntityTypeConfiguration<Invoice>
|
||||||
{
|
{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using InvoiceMaster.Core.Entities;
|
using FiscalFlow.Core.Entities;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
|
||||||
namespace InvoiceMaster.Infrastructure.Data.Configurations;
|
namespace FiscalFlow.Infrastructure.Data.Configurations;
|
||||||
|
|
||||||
public class SupplierCacheConfiguration : IEntityTypeConfiguration<SupplierCache>
|
public class SupplierCacheConfiguration : IEntityTypeConfiguration<SupplierCache>
|
||||||
{
|
{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using InvoiceMaster.Core.Entities;
|
using FiscalFlow.Core.Entities;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
|
||||||
namespace InvoiceMaster.Infrastructure.Data.Configurations;
|
namespace FiscalFlow.Infrastructure.Data.Configurations;
|
||||||
|
|
||||||
public class UserConfiguration : IEntityTypeConfiguration<User>
|
public class UserConfiguration : IEntityTypeConfiguration<User>
|
||||||
{
|
{
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
using InvoiceMaster.Core.Interfaces;
|
using FiscalFlow.Core.Interfaces;
|
||||||
using InvoiceMaster.Infrastructure.Data;
|
using FiscalFlow.Infrastructure.Data;
|
||||||
using InvoiceMaster.Infrastructure.Repositories;
|
using FiscalFlow.Infrastructure.Repositories;
|
||||||
using InvoiceMaster.Infrastructure.Services;
|
using FiscalFlow.Infrastructure.Services;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace InvoiceMaster.Infrastructure.Extensions;
|
namespace FiscalFlow.Infrastructure.Extensions;
|
||||||
|
|
||||||
public static class DependencyInjection
|
public static class DependencyInjection
|
||||||
{
|
{
|
||||||
@@ -1,26 +1,26 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AssemblyName>InvoiceMaster.Infrastructure</AssemblyName>
|
<AssemblyName>FiscalFlow.Infrastructure</AssemblyName>
|
||||||
<RootNamespace>InvoiceMaster.Infrastructure</RootNamespace>
|
<RootNamespace>FiscalFlow.Infrastructure</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.0" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.0">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="10.0.0" />
|
||||||
<PackageReference Include="Azure.Storage.Blobs" Version="12.19.1" />
|
<PackageReference Include="Azure.Storage.Blobs" Version="12.23.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.0" />
|
||||||
<PackageReference Include="Polly" Version="8.2.0" />
|
<PackageReference Include="Polly" Version="8.5.0" />
|
||||||
<PackageReference Include="Polly.Extensions.Http" Version="3.0.0" />
|
<PackageReference Include="Polly.Extensions.Http" Version="3.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\InvoiceMaster.Application\InvoiceMaster.Application.csproj" />
|
<ProjectReference Include="..\FiscalFlow.Application\FiscalFlow.Application.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using InvoiceMaster.Core.Interfaces;
|
using FiscalFlow.Core.Interfaces;
|
||||||
using InvoiceMaster.Infrastructure.Data;
|
using FiscalFlow.Infrastructure.Data;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace InvoiceMaster.Infrastructure.Repositories;
|
namespace FiscalFlow.Infrastructure.Repositories;
|
||||||
|
|
||||||
public class Repository<T> : IRepository<T> where T : class
|
public class Repository<T> : IRepository<T> where T : class
|
||||||
{
|
{
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using InvoiceMaster.Core.Interfaces;
|
using FiscalFlow.Core.Interfaces;
|
||||||
using InvoiceMaster.Infrastructure.Data;
|
using FiscalFlow.Infrastructure.Data;
|
||||||
|
|
||||||
namespace InvoiceMaster.Infrastructure.Repositories;
|
namespace FiscalFlow.Infrastructure.Repositories;
|
||||||
|
|
||||||
public class UnitOfWork : IUnitOfWork
|
public class UnitOfWork : IUnitOfWork
|
||||||
{
|
{
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
using Azure.Storage.Blobs;
|
using Azure.Storage.Blobs;
|
||||||
using Azure.Storage.Blobs.Models;
|
using Azure.Storage.Blobs.Models;
|
||||||
using InvoiceMaster.Core.Interfaces;
|
using FiscalFlow.Core.Interfaces;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace InvoiceMaster.Infrastructure.Services;
|
namespace FiscalFlow.Infrastructure.Services;
|
||||||
|
|
||||||
public class AzureBlobStorageService : IBlobStorageService
|
public class AzureBlobStorageService : IBlobStorageService
|
||||||
{
|
{
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
using InvoiceMaster.Core.Interfaces;
|
using FiscalFlow.Core.Interfaces;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace InvoiceMaster.Infrastructure.Services;
|
namespace FiscalFlow.Infrastructure.Services;
|
||||||
|
|
||||||
public class OcrService : IOcrService
|
public class OcrService : IOcrService
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// <autogenerated />
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
[assembly: System.Reflection.AssemblyCompanyAttribute("FiscalFlow.Infrastructure")]
|
||||||
|
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||||
|
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||||
|
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+05ea67144f6a97e372ca4293ce2393e15a3f6bb7")]
|
||||||
|
[assembly: System.Reflection.AssemblyProductAttribute("FiscalFlow.Infrastructure")]
|
||||||
|
[assembly: System.Reflection.AssemblyTitleAttribute("FiscalFlow.Infrastructure")]
|
||||||
|
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||||
|
|
||||||
|
// Generated by the MSBuild WriteCodeFragment class.
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
c1abda544679cc02d15e49d9a1ea8ab47eb3d4dceeb77000b285aa23e7159380
|
||||||
@@ -9,7 +9,7 @@ build_property.InvariantGlobalization =
|
|||||||
build_property.PlatformNeutralAssembly =
|
build_property.PlatformNeutralAssembly =
|
||||||
build_property.EnforceExtendedAnalyzerRules =
|
build_property.EnforceExtendedAnalyzerRules =
|
||||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||||
build_property.RootNamespace = InvoiceMaster.Infrastructure
|
build_property.RootNamespace = FiscalFlow.Infrastructure
|
||||||
build_property.ProjectDir = C:\Users\yaoji\git\ColaCoder\accounting-system\backend\src\InvoiceMaster.Infrastructure\
|
build_property.ProjectDir = C:\Users\yaoji\git\ColaCoder\accounting-system\backend\src\InvoiceMaster.Infrastructure\
|
||||||
build_property.EnableComHosting =
|
build_property.EnableComHosting =
|
||||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// <auto-generated/>
|
||||||
|
global using System;
|
||||||
|
global using System.Collections.Generic;
|
||||||
|
global using System.IO;
|
||||||
|
global using System.Linq;
|
||||||
|
global using System.Net.Http;
|
||||||
|
global using System.Threading;
|
||||||
|
global using System.Threading.Tasks;
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
{
|
||||||
|
"format": 1,
|
||||||
|
"restore": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj": {}
|
||||||
|
},
|
||||||
|
"projects": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"projectName": "InvoiceMaster.Application",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj",
|
||||||
|
"packagesPath": "C:\\Users\\yaoji\\.nuget\\packages\\",
|
||||||
|
"outputPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\obj\\",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"fallbackFolders": [
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||||
|
],
|
||||||
|
"configFilePaths": [
|
||||||
|
"C:\\Users\\yaoji\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net8.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||||
|
"https://api.nuget.org/v3/index.json": {},
|
||||||
|
"https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"projectReferences": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj": {
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"allWarningsAsErrors": true,
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restoreAuditProperties": {
|
||||||
|
"enableAudit": "true",
|
||||||
|
"auditLevel": "low",
|
||||||
|
"auditMode": "direct"
|
||||||
|
},
|
||||||
|
"SdkAnalysisLevel": "10.0.100"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"dependencies": {
|
||||||
|
"AutoMapper": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[12.0.1, )"
|
||||||
|
},
|
||||||
|
"FluentValidation": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[11.8.1, )"
|
||||||
|
},
|
||||||
|
"MediatR": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[12.2.0, )"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"StyleCop.Analyzers": {
|
||||||
|
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
|
||||||
|
"suppressParent": "All",
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[1.2.0-beta.556, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48",
|
||||||
|
"net481"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.102/PortableRuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"projectName": "InvoiceMaster.Core",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\InvoiceMaster.Core.csproj",
|
||||||
|
"packagesPath": "C:\\Users\\yaoji\\.nuget\\packages\\",
|
||||||
|
"outputPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Core\\obj\\",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"fallbackFolders": [
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||||
|
],
|
||||||
|
"configFilePaths": [
|
||||||
|
"C:\\Users\\yaoji\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net8.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||||
|
"https://api.nuget.org/v3/index.json": {},
|
||||||
|
"https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"projectReferences": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"allWarningsAsErrors": true,
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restoreAuditProperties": {
|
||||||
|
"enableAudit": "true",
|
||||||
|
"auditLevel": "low",
|
||||||
|
"auditMode": "direct"
|
||||||
|
},
|
||||||
|
"SdkAnalysisLevel": "10.0.100"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"dependencies": {
|
||||||
|
"StyleCop.Analyzers": {
|
||||||
|
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
|
||||||
|
"suppressParent": "All",
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[1.2.0-beta.556, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48",
|
||||||
|
"net481"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.102/PortableRuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"projectName": "InvoiceMaster.Infrastructure",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"packagesPath": "C:\\Users\\yaoji\\.nuget\\packages\\",
|
||||||
|
"outputPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\obj\\",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"fallbackFolders": [
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||||
|
],
|
||||||
|
"configFilePaths": [
|
||||||
|
"C:\\Users\\yaoji\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||||
|
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net8.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||||
|
"https://api.nuget.org/v3/index.json": {},
|
||||||
|
"https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"projectReferences": {
|
||||||
|
"C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj": {
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Application\\InvoiceMaster.Application.csproj"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"allWarningsAsErrors": true,
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restoreAuditProperties": {
|
||||||
|
"enableAudit": "true",
|
||||||
|
"auditLevel": "low",
|
||||||
|
"auditMode": "direct"
|
||||||
|
},
|
||||||
|
"SdkAnalysisLevel": "10.0.100"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"dependencies": {
|
||||||
|
"Azure.Storage.Blobs": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[12.19.1, )"
|
||||||
|
},
|
||||||
|
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"Microsoft.EntityFrameworkCore": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"Microsoft.EntityFrameworkCore.Tools": {
|
||||||
|
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
|
||||||
|
"suppressParent": "All",
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Http": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"Npgsql.EntityFrameworkCore.PostgreSQL": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.0.0, )"
|
||||||
|
},
|
||||||
|
"Polly": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[8.2.0, )"
|
||||||
|
},
|
||||||
|
"Polly.Extensions.Http": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[3.0.0, )"
|
||||||
|
},
|
||||||
|
"StyleCop.Analyzers": {
|
||||||
|
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
|
||||||
|
"suppressParent": "All",
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[1.2.0-beta.556, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48",
|
||||||
|
"net481"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.102/PortableRuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||||
|
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||||
|
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||||
|
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||||
|
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\yaoji\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
|
||||||
|
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||||
|
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<SourceRoot Include="C:\Users\yaoji\.nuget\packages\" />
|
||||||
|
<SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore\8.0.0\buildTransitive\net8.0\Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore\8.0.0\buildTransitive\net8.0\Microsoft.EntityFrameworkCore.props')" />
|
||||||
|
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore.design\8.0.0\build\net8.0\Microsoft.EntityFrameworkCore.Design.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore.design\8.0.0\build\net8.0\Microsoft.EntityFrameworkCore.Design.props')" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<PkgStyleCop_Analyzers_Unstable Condition=" '$(PkgStyleCop_Analyzers_Unstable)' == '' ">C:\Users\yaoji\.nuget\packages\stylecop.analyzers.unstable\1.2.0.556</PkgStyleCop_Analyzers_Unstable>
|
||||||
|
<PkgMicrosoft_CodeAnalysis_Analyzers Condition=" '$(PkgMicrosoft_CodeAnalysis_Analyzers)' == '' ">C:\Users\yaoji\.nuget\packages\microsoft.codeanalysis.analyzers\3.3.3</PkgMicrosoft_CodeAnalysis_Analyzers>
|
||||||
|
<PkgMicrosoft_EntityFrameworkCore_Tools Condition=" '$(PkgMicrosoft_EntityFrameworkCore_Tools)' == '' ">C:\Users\yaoji\.nuget\packages\microsoft.entityframeworkcore.tools\8.0.0</PkgMicrosoft_EntityFrameworkCore_Tools>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<Import Project="$(NuGetPackageRoot)system.text.json\8.0.0\buildTransitive\net6.0\System.Text.Json.targets" Condition="Exists('$(NuGetPackageRoot)system.text.json\8.0.0\buildTransitive\net6.0\System.Text.Json.targets')" />
|
||||||
|
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||||
|
<Import Project="$(NuGetPackageRoot)microsoft.extensions.options\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Options.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.options\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Options.targets')" />
|
||||||
|
<Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.binder\8.0.0\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.binder\8.0.0\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets')" />
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
3758
backend/src/FiscalFlow.Infrastructure/obj/project.assets.json
Normal file
3758
backend/src/FiscalFlow.Infrastructure/obj/project.assets.json
Normal file
File diff suppressed because it is too large
Load Diff
248
backend/src/FiscalFlow.Infrastructure/obj/project.nuget.cache
Normal file
248
backend/src/FiscalFlow.Infrastructure/obj/project.nuget.cache
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"dgSpecHash": "8okLAOOEnqI=",
|
||||||
|
"success": false,
|
||||||
|
"projectFilePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"expectedPackageFiles": [
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\automapper\\12.0.1\\automapper.12.0.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\azure.core\\1.36.0\\azure.core.1.36.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\azure.storage.blobs\\12.19.1\\azure.storage.blobs.12.19.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\azure.storage.common\\12.18.1\\azure.storage.common.12.18.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\fluentvalidation\\11.8.1\\fluentvalidation.11.8.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\humanizer.core\\2.14.1\\humanizer.core.2.14.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\mediatr\\12.2.0\\mediatr.12.2.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\mediatr.contracts\\2.0.1\\mediatr.contracts.2.0.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.aspnetcore.cryptography.internal\\8.0.0\\microsoft.aspnetcore.cryptography.internal.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.aspnetcore.cryptography.keyderivation\\8.0.0\\microsoft.aspnetcore.cryptography.keyderivation.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.aspnetcore.identity.entityframeworkcore\\8.0.0\\microsoft.aspnetcore.identity.entityframeworkcore.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.bcl.asyncinterfaces\\6.0.0\\microsoft.bcl.asyncinterfaces.6.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.codeanalysis.analyzers\\3.3.3\\microsoft.codeanalysis.analyzers.3.3.3.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.codeanalysis.common\\4.5.0\\microsoft.codeanalysis.common.4.5.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.codeanalysis.csharp\\4.5.0\\microsoft.codeanalysis.csharp.4.5.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.codeanalysis.csharp.workspaces\\4.5.0\\microsoft.codeanalysis.csharp.workspaces.4.5.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.codeanalysis.workspaces.common\\4.5.0\\microsoft.codeanalysis.workspaces.common.4.5.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.csharp\\4.7.0\\microsoft.csharp.4.7.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.entityframeworkcore\\8.0.0\\microsoft.entityframeworkcore.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.entityframeworkcore.abstractions\\8.0.0\\microsoft.entityframeworkcore.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.entityframeworkcore.analyzers\\8.0.0\\microsoft.entityframeworkcore.analyzers.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.entityframeworkcore.design\\8.0.0\\microsoft.entityframeworkcore.design.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.entityframeworkcore.relational\\8.0.0\\microsoft.entityframeworkcore.relational.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.entityframeworkcore.tools\\8.0.0\\microsoft.entityframeworkcore.tools.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.caching.abstractions\\8.0.0\\microsoft.extensions.caching.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.caching.memory\\8.0.0\\microsoft.extensions.caching.memory.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.configuration\\8.0.0\\microsoft.extensions.configuration.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.configuration.abstractions\\8.0.0\\microsoft.extensions.configuration.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.configuration.binder\\8.0.0\\microsoft.extensions.configuration.binder.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.dependencyinjection\\8.0.0\\microsoft.extensions.dependencyinjection.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.dependencyinjection.abstractions\\8.0.0\\microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.dependencymodel\\8.0.0\\microsoft.extensions.dependencymodel.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.diagnostics\\8.0.0\\microsoft.extensions.diagnostics.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.diagnostics.abstractions\\8.0.0\\microsoft.extensions.diagnostics.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.http\\8.0.0\\microsoft.extensions.http.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.identity.core\\8.0.0\\microsoft.extensions.identity.core.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.identity.stores\\8.0.0\\microsoft.extensions.identity.stores.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.logging\\8.0.0\\microsoft.extensions.logging.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.logging.abstractions\\8.0.0\\microsoft.extensions.logging.abstractions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.options\\8.0.0\\microsoft.extensions.options.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.options.configurationextensions\\8.0.0\\microsoft.extensions.options.configurationextensions.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\microsoft.extensions.primitives\\8.0.0\\microsoft.extensions.primitives.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\mono.texttemplating\\2.2.1\\mono.texttemplating.2.2.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\npgsql\\8.0.0\\npgsql.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\npgsql.entityframeworkcore.postgresql\\8.0.0\\npgsql.entityframeworkcore.postgresql.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\polly\\8.2.0\\polly.8.2.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\polly.core\\8.2.0\\polly.core.8.2.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\polly.extensions.http\\3.0.0\\polly.extensions.http.3.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\stylecop.analyzers\\1.2.0-beta.556\\stylecop.analyzers.1.2.0-beta.556.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\stylecop.analyzers.unstable\\1.2.0.556\\stylecop.analyzers.unstable.1.2.0.556.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.codedom\\4.4.0\\system.codedom.4.4.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.collections.immutable\\6.0.0\\system.collections.immutable.6.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.composition\\6.0.0\\system.composition.6.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.composition.attributedmodel\\6.0.0\\system.composition.attributedmodel.6.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.composition.convention\\6.0.0\\system.composition.convention.6.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.composition.hosting\\6.0.0\\system.composition.hosting.6.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.composition.runtime\\6.0.0\\system.composition.runtime.6.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.composition.typedparts\\6.0.0\\system.composition.typedparts.6.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.diagnostics.diagnosticsource\\8.0.0\\system.diagnostics.diagnosticsource.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.io.hashing\\6.0.0\\system.io.hashing.6.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.io.pipelines\\6.0.3\\system.io.pipelines.6.0.3.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.memory.data\\1.0.2\\system.memory.data.1.0.2.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.numerics.vectors\\4.5.0\\system.numerics.vectors.4.5.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.reflection.metadata\\6.0.1\\system.reflection.metadata.6.0.1.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.runtime.compilerservices.unsafe\\6.0.0\\system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.text.encoding.codepages\\6.0.0\\system.text.encoding.codepages.6.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.text.encodings.web\\8.0.0\\system.text.encodings.web.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.text.json\\8.0.0\\system.text.json.8.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.threading.channels\\6.0.0\\system.threading.channels.6.0.0.nupkg.sha512",
|
||||||
|
"C:\\Users\\yaoji\\.nuget\\packages\\system.threading.tasks.extensions\\4.5.4\\system.threading.tasks.extensions.4.5.4.nupkg.sha512"
|
||||||
|
],
|
||||||
|
"logs": [
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1301",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.\r\n Response status code does not indicate success: 401 (Unauthorized).",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "NU1900",
|
||||||
|
"level": "Error",
|
||||||
|
"message": "Warning As Error: Error occurred while getting package vulnerability data: Unable to load the service index for source https://pkgs.dev.azure.com/billodev/2c2b8bbf-61f2-43f4-b4bb-2017cef20a2c/_packaging/BilloFeed/nuget/v3/index.json.",
|
||||||
|
"projectPath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"filePath": "C:\\Users\\yaoji\\git\\ColaCoder\\accounting-system\\backend\\src\\InvoiceMaster.Infrastructure\\InvoiceMaster.Infrastructure.csproj",
|
||||||
|
"targetGraphs": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user