Change file structure for raw data archival feature

This commit is contained in:
Eugene Burmakin 2025-12-07 14:29:39 +01:00
parent fd7467e63b
commit 973a4aae84
5 changed files with 26 additions and 10 deletions

View file

@ -28,7 +28,7 @@ module Points
end end
def filename def filename
"raw_data_#{user_id}_#{year}_#{format('%02d', month)}_chunk#{format('%03d', chunk_number)}.jsonl.gz" "raw_data_archives/#{user_id}/#{year}/#{format('%02d', month)}/#{format('%03d', chunk_number)}.jsonl.gz"
end end
def size_mb def size_mb

View file

@ -164,12 +164,13 @@ module Points
) )
# Attach compressed file via ActiveStorage # Attach compressed file via ActiveStorage
filename = "raw_data_#{user_id}_#{year}_#{format('%02d', month)}_chunk#{format('%03d', chunk_number)}.jsonl.gz" # Uses directory structure: raw_data_archives/:user_id/:year/:month/:chunk.jsonl.gz
# The key parameter controls the actual storage path
archive.file.attach( archive.file.attach(
io: StringIO.new(compressed_data), io: StringIO.new(compressed_data),
filename: filename, filename: "#{format('%03d', chunk_number)}.jsonl.gz",
content_type: 'application/gzip' content_type: 'application/gzip',
key: "raw_data_archives/#{user_id}/#{year}/#{format('%02d', month)}/#{format('%03d', chunk_number)}.jsonl.gz"
) )
archive archive

View file

@ -7,18 +7,25 @@ RSpec.describe Points::RawData::ArchiveJob, type: :job do
let(:archiver) { instance_double(Points::RawData::Archiver) } let(:archiver) { instance_double(Points::RawData::Archiver) }
before do before do
# Enable archival for tests
allow(ENV).to receive(:[]).and_call_original
allow(ENV).to receive(:[]).with('ARCHIVE_RAW_DATA').and_return('true')
allow(Points::RawData::Archiver).to receive(:new).and_return(archiver) allow(Points::RawData::Archiver).to receive(:new).and_return(archiver)
allow(archiver).to receive(:call).and_return({ processed: 5, archived: 100, failed: 0 })
end end
it 'calls the archiver service' do it 'calls the archiver service' do
expect(archiver).to receive(:call).and_return({ processed: 5, archived: 100, failed: 0 }) expect(archiver).to receive(:call)
described_class.perform_now described_class.perform_now
end end
context 'when archiver raises an error' do context 'when archiver raises an error' do
let(:error) { StandardError.new('Archive failed') }
before do before do
allow(archiver).to receive(:call).and_raise(StandardError, 'Archive failed') allow(archiver).to receive(:call).and_raise(error)
end end
it 're-raises the error' do it 're-raises the error' do
@ -26,6 +33,14 @@ RSpec.describe Points::RawData::ArchiveJob, type: :job do
described_class.perform_now described_class.perform_now
end.to raise_error(StandardError, 'Archive failed') end.to raise_error(StandardError, 'Archive failed')
end end
it 'reports the error before re-raising' do
expect(ExceptionReporter).to receive(:call).with(error, 'Points raw data archival job failed')
expect do
described_class.perform_now
end.to raise_error(StandardError)
end
end end
end end
end end

View file

@ -64,9 +64,9 @@ RSpec.describe Points::RawDataArchive, type: :model do
end end
describe '#filename' do describe '#filename' do
it 'generates correct filename' do it 'generates correct filename with directory structure' do
archive = build(:points_raw_data_archive, user_id: 123, year: 2024, month: 6, chunk_number: 5) archive = build(:points_raw_data_archive, user_id: 123, year: 2024, month: 6, chunk_number: 5)
expect(archive.filename).to eq('raw_data_123_2024_06_chunk005.jsonl.gz') expect(archive.filename).to eq('raw_data_archives/123/2024/06/005.jsonl.gz')
end end
end end

View file

@ -131,7 +131,7 @@ RSpec.describe Points::RawData::Archiver do
archive = user.raw_data_archives.last archive = user.raw_data_archives.last
expect(archive.file).to be_attached expect(archive.file).to be_attached
expect(archive.file.filename.to_s).to match(/raw_data_.*_chunk001\.jsonl\.gz/) expect(archive.file.key).to match(%r{raw_data_archives/\d+/\d{4}/\d{2}/001\.jsonl\.gz})
end end
end end