An open API service indexing awesome lists of open source software.

https://github.com/giljr/how_to_storing_fiscal_data

You now have a production-ready Rails 8 app capable of parsing and storing fiscal data from RCAD-formatted files.
https://github.com/giljr/how_to_storing_fiscal_data

batch-processing fileutils fiscalization moving-processed-file rails8 rcad transactions upload-file

Last synced: 10 months ago
JSON representation

You now have a production-ready Rails 8 app capable of parsing and storing fiscal data from RCAD-formatted files.

Awesome Lists containing this project

README

          

# ๐Ÿš€ Building a Robust RCAD File Upload Service with Rails 8

### _From Project Setup to Service Execution โ€” A Step-by-Step Guide Using Ruby 3.3+, Transaction, FileUtils and Clean Architecture_

---

## ๐Ÿ“˜ About the Project

RCAD is a fiscal data initiative by Brazil's **CONFAZ** (National Council for Fiscal Policy), enabling structured communication across all 27 state tax departments. This project simulates a **real-world use case**, where you'll build a robust upload and parsing system using a clean, modular Rails 8 architecture.

Though the data used here is **fictitious**, the structure is suitable for production with minimal adjustments.

---

## ๐ŸŽฏ Objective

Create a Rails 8 app with:

- โœ… Ruby 3.3+ support
- โœ… Batch processing with `activerecord-import`
- โœ… Transaction safety and error rollback
- โœ… Modular parsing using `.detalhe(row)`
- โœ… Directory structure for organized file management
- โœ… API endpoint for triggering the service
- โœ… Ready for logging, testing, and extension

---

## ๐Ÿ’ก Highlights

- ๐Ÿ”„ Batch import with `batch_size: 10000` for performance
- ๐Ÿ”’ Safe transactions using `ActiveRecord::Base.transaction`
- ๐Ÿงฑ Clean separation of logic using methods like `cliente(row)`
- ๐Ÿ“ Files moved after processing with `FileUtils.mv`

---

## ๐Ÿš€ Let's Get Started!

> โš  If you get stuck, feel free to check the [GitHub repo](#).

---

### 1. Project Setup ๐Ÿ› 

```bash
rails new rcad_app --api
cd rcad_app
```
### 2. Add Required Gems ๐Ÿงฉ

In your Gemfile:
```ruby
gem "activerecord-import"
gem "tty-logger"
gem "tty-spinner"
```
Then run:

bundle install

### 3. Generate Models ๐Ÿ—ƒ๏ธ
```ruby
rails g model MeioDeCaptura tipo_tecn:integer term_prop:integer marca:string mestre:references
rails g model IpParceira cnpj:string nome:string nome_resp:string fone:string email:string mestre:references
rails g model Adquirencia cnpj_adqui:string mestre:references
rails g model UfDestinataria uf:string qtd:integer mestre:references
rails g model Autorizacao tp_autoriz:integer cnpj:string tp_transac:integer dt_ini_aut:date dt_fim_aut:date mestre:references
rails g model ContadorRegistro qtd_b:integer qtd_c:integer qtd_d:integer qtd_e:integer qtd_f:integer qtd_g:integer qtd_h:integer mestre:references
```
Adjust model attributes as needed based on the .detalhe(row) parsing logic.

### 4. Configure File Paths ๐Ÿ”ง

In `config/application.rb`:
```ruby
module RcadApp
class Application < Rails::Application
config.load_defaults 8.0

config.rcad_path = {
original: Rails.root.join('rcad_files/original'),
processados: Rails.root.join('rcad_files/processados'),
erros: Rails.root.join('rcad_files/erros')
}
end
end
```
### 5. Create Directories

mkdir -p rcad_files/{original,processados,erros}

You can now place .TXT files in rcad_files/original.
### 6. Create the RCAD Service ๐Ÿง 

File: app/services/cargas/rcad_carga.rb

๐Ÿ“Œ See full implementation above โ€” includes collection setup, transaction handling, row dispatching, and directory movement.

### 7. Implement .detalhe(row) in Models ๐Ÿงฑ

Example for Cliente:
```ruby
class Cliente < ApplicationRecord
belongs_to :mestre

def detalhe(row)
linha = row.split('|')
self.cnpj = linha[2]
self.cpf = linha[3]
self.dt_credenciamento = parse_data(linha[4])
end

private

def parse_data(str)
Date.strptime(str, '%Y%m%d') rescue nil
end
end
```
Repeat for other models based on their layout in the RCAD spec.
### 8. Define Custom Inflection Rules

In config/initializers/inflections.rb:
```ruby
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.irregular 'adquirencia', 'adquirencias'
inflect.irregular 'uf_destinataria', 'uf_destinatarias'
inflect.irregular 'autorizacao', 'autorizacoes'
end
```
This ensures proper pluralization when generating models or controllers.
### 9. Run Migrations ๐Ÿ”ƒ

rails db:create db:migrate

### 10. Add API Endpoint for File Upload ๐Ÿงช
Generate controller:
```ruby
rails g controller api/v1/rcad --skip-template-engine --no-assets --api

Add action:

module Api
module V1
class RcadController < ApplicationController
def processar
result = Cargas::RcadCarga.new
render json: { message: 'RCAD file processed successfully' }, status: :ok
rescue => e
render json: { error: e.message }, status: :unprocessable_entity
end
end
end
end
```
Add route:

# config/routes.rb
```ruby
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
post 'rcad/processar', to: 'rcad#processar'
end
end
end
```
### 11. Test It via Postman or Curl ๐Ÿ’ฌ

Start the server:

rails s

Then run:

curl -X POST http://localhost:3000/api/v1/rcad/processar

You should receive:

{"message":"RCAD file processed successfully"}

### 12. Manual Test via Console ๐Ÿงช

rails console
Then

Cargas::RcadCarga.new

## ๐Ÿ“ˆ Improvements Inspired by External Review

See detailed [Suggestions for Improvement](./IMPROVEMENT.md), based on a review and best practices analysis.

โœ… Done!

You now have a production-ready Rails 8 app capable of parsing and storing fiscal data from RCAD-formatted files.
## Acknowledgements

- [Jeovan Farias](https://www.linkedin.com/in/jeovan-f-6283b8145/)

## Authors

- [Jaythree](https://www.linkedin.com/in/giljrx/)

## License

[MIT](https://choosealicense.com/licenses/mit/)